Merge branch 'master' of github.com:mattermost/mattermost-server into top-dms-clean

Этот коммит содержится в:
Shivashis Padhi
2022-08-10 21:00:57 +05:30
родитель 4fc8ef0125 1738bd6e92
Коммит 4ec3eade3b
214 изменённых файлов: 3322 добавлений и 3004 удалений

Просмотреть файл

@@ -149,12 +149,12 @@ TEMPLATES_DIR=templates
PLUGIN_PACKAGES ?= mattermost-plugin-antivirus-v0.1.2 PLUGIN_PACKAGES ?= mattermost-plugin-antivirus-v0.1.2
PLUGIN_PACKAGES += mattermost-plugin-autolink-v1.2.2 PLUGIN_PACKAGES += mattermost-plugin-autolink-v1.2.2
PLUGIN_PACKAGES += mattermost-plugin-aws-SNS-v1.2.0 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-channel-export-v1.0.0
PLUGIN_PACKAGES += mattermost-plugin-custom-attributes-v1.3.0 PLUGIN_PACKAGES += mattermost-plugin-custom-attributes-v1.3.0
PLUGIN_PACKAGES += mattermost-plugin-github-v2.0.1 PLUGIN_PACKAGES += mattermost-plugin-github-v2.0.1
PLUGIN_PACKAGES += mattermost-plugin-gitlab-v1.3.0 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-jenkins-v1.1.0
PLUGIN_PACKAGES += mattermost-plugin-jira-v2.4.0 PLUGIN_PACKAGES += mattermost-plugin-jira-v2.4.0
PLUGIN_PACKAGES += mattermost-plugin-nps-v1.2.0 PLUGIN_PACKAGES += mattermost-plugin-nps-v1.2.0
@@ -184,7 +184,10 @@ endif
# Prepare optional Boards build. # Prepare optional Boards build.
BOARDS_PACKAGES=$(shell $(GO) list $(BUILD_BOARDS_DIR)/server/...) BOARDS_PACKAGES=$(shell $(GO) list $(BUILD_BOARDS_DIR)/server/...)
ifeq ($(BUILD_BOARDS),true) 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 echo Boards build selected, preparing)
IGNORE:=$(shell rm -f imports/boards_imports.go) IGNORE:=$(shell rm -f imports/boards_imports.go)
IGNORE:=$(shell cp $(BUILD_BOARDS_DIR)/mattermost-plugin/product/imports/boards_imports.go imports/) IGNORE:=$(shell cp $(BUILD_BOARDS_DIR)/mattermost-plugin/product/imports/boards_imports.go imports/)
@@ -317,7 +320,7 @@ ifeq ($(BUILD_ENTERPRISE_READY),true)
endif endif
ifeq ($(BUILD_BOARDS),true) ifeq ($(BUILD_BOARDS),true)
ifneq ($(MM_NO_BOARDS_LINT),true) ifneq ($(MM_NO_BOARDS_LINT),true)
$(GOBIN)/golangci-lint run $(BUILD_BOARDS_DIR)/server/... cd $(BUILD_BOARDS_DIR); make server-lint
endif endif
endif endif

Просмотреть файл

@@ -10,7 +10,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"math/rand" "math/rand"
"net" "net"
"net/http" "net/http"
@@ -84,7 +83,7 @@ func SetMainHelper(mh *testlib.MainHelper) {
func setupTestHelper(dbStore store.Store, searchEngine *searchengine.Broker, enterprise bool, includeCache bool, func setupTestHelper(dbStore store.Store, searchEngine *searchengine.Broker, enterprise bool, includeCache bool,
updateConfig func(*model.Config), options []app.Option) *TestHelper { updateConfig func(*model.Config), options []app.Option) *TestHelper {
tempWorkspace, err := ioutil.TempDir("", "apptest") tempWorkspace, err := os.MkdirTemp("", "apptest")
if err != nil { if err != nil {
panic(err) panic(err)
} }

Просмотреть файл

@@ -5,7 +5,7 @@ package api4
import ( import (
"encoding/json" "encoding/json"
"io/ioutil" "io"
"strings" "strings"
"testing" "testing"
@@ -461,7 +461,7 @@ func TestPatchBot(t *testing.T) {
r, err := th.Client.DoAPIPut("/bots/"+createdBot.UserId, `{"creator_id":"`+th.BasicUser2.Id+`"}`) r, err := th.Client.DoAPIPut("/bots/"+createdBot.UserId, `{"creator_id":"`+th.BasicUser2.Id+`"}`)
require.NoError(t, err) require.NoError(t, err)
defer func() { defer func() {
_, _ = ioutil.ReadAll(r.Body) _, _ = io.ReadAll(r.Body)
_ = r.Body.Close() _ = r.Body.Close()
}() }()
var patchedBot *model.Bot var patchedBot *model.Bot

Просмотреть файл

@@ -1820,7 +1820,7 @@ func updateChannelScheme(c *Context, w http.ResponseWriter, r *http.Request) {
auditRec.AddEventParameter("scheme_id", *schemeID) auditRec.AddEventParameter("scheme_id", *schemeID)
if c.App.Channels().License() == nil { 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 return
} }
@@ -1891,23 +1891,23 @@ func channelMembersMinusGroupMembers(c *Context, w http.ResponseWriter, r *http.
return return
} }
users, totalCount, err := c.App.ChannelMembersMinusGroupMembers( users, totalCount, appErr := c.App.ChannelMembersMinusGroupMembers(
c.Params.ChannelId, c.Params.ChannelId,
groupIDs, groupIDs,
c.Params.Page, c.Params.Page,
c.Params.PerPage, c.Params.PerPage,
) )
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
b, marshalErr := json.Marshal(&model.UsersWithGroupsAndCount{ b, err := json.Marshal(&model.UsersWithGroupsAndCount{
Users: users, Users: users,
Count: totalCount, Count: totalCount,
}) })
if marshalErr != nil { if err != nil {
c.Err = model.NewAppError("Api4.channelMembersMinusGroupMembers", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("Api4.channelMembersMinusGroupMembers", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
@@ -1916,7 +1916,7 @@ func channelMembersMinusGroupMembers(c *Context, w http.ResponseWriter, r *http.
func channelMemberCountsByGroup(c *Context, w http.ResponseWriter, r *http.Request) { func channelMemberCountsByGroup(c *Context, w http.ResponseWriter, r *http.Request) {
if c.App.Channels().License() == nil { 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 return
} }
@@ -1932,15 +1932,15 @@ func channelMemberCountsByGroup(c *Context, w http.ResponseWriter, r *http.Reque
includeTimezones := r.URL.Query().Get("include_timezones") == "true" includeTimezones := r.URL.Query().Get("include_timezones") == "true"
channelMemberCounts, err := c.App.GetMemberCountsByGroup(app.WithMaster(context.Background()), c.Params.ChannelId, includeTimezones) channelMemberCounts, appErr := c.App.GetMemberCountsByGroup(app.WithMaster(context.Background()), c.Params.ChannelId, includeTimezones)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
b, marshalErr := json.Marshal(channelMemberCounts) b, err := json.Marshal(channelMemberCounts)
if marshalErr != nil { if err != nil {
c.Err = model.NewAppError("Api4.channelMemberCountsByGroup", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("Api4.channelMemberCountsByGroup", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return 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) { func getChannelModerations(c *Context, w http.ResponseWriter, r *http.Request) {
if c.App.Channels().License() == nil { 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 return
} }
@@ -1963,21 +1963,21 @@ func getChannelModerations(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
channel, err := c.App.GetChannel(c.AppContext, c.Params.ChannelId) channel, appErr := c.App.GetChannel(c.AppContext, c.Params.ChannelId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
channelModerations, err := c.App.GetChannelModerationsForChannel(c.AppContext, channel) channelModerations, appErr := c.App.GetChannelModerationsForChannel(c.AppContext, channel)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
b, marshalErr := json.Marshal(channelModerations) b, err := json.Marshal(channelModerations)
if marshalErr != nil { if err != nil {
c.Err = model.NewAppError("Api4.getChannelModerations", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("Api4.getChannelModerations", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return 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) { func patchChannelModerations(c *Context, w http.ResponseWriter, r *http.Request) {
if c.App.Channels().License() == nil { 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 return
} }
@@ -2024,9 +2024,9 @@ func patchChannelModerations(c *Context, w http.ResponseWriter, r *http.Request)
} }
auditRec.AddEventParameter("patch", channelModerationsPatch) auditRec.AddEventParameter("patch", channelModerationsPatch)
b, marshalErr := json.Marshal(channelModerations) b, err := json.Marshal(channelModerations)
if marshalErr != nil { if err != nil {
c.Err = model.NewAppError("Api4.patchChannelModerations", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("Api4.patchChannelModerations", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }

Просмотреть файл

@@ -23,15 +23,15 @@ func getCategoriesForTeamForUser(c *Context, w http.ResponseWriter, r *http.Requ
return return
} }
categories, err := c.App.GetSidebarCategoriesForTeamForUser(c.AppContext, c.Params.UserId, c.Params.TeamId) categories, appErr := c.App.GetSidebarCategoriesForTeamForUser(c.AppContext, c.Params.UserId, c.Params.TeamId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
categoriesJSON, jsonErr := json.Marshal(categories) categoriesJSON, err := json.Marshal(categories)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getCategoriesForTeamForUser", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getCategoriesForTeamForUser", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
@@ -70,9 +70,9 @@ func createCategoryForTeamForUser(c *Context, w http.ResponseWriter, r *http.Req
return return
} }
categoryJSON, jsonErr := json.Marshal(category) categoryJSON, err := json.Marshal(category)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("createCategoryForTeamForUser", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("createCategoryForTeamForUser", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
@@ -92,13 +92,16 @@ func getCategoryOrderForTeamForUser(c *Context, w http.ResponseWriter, r *http.R
return return
} }
order, err := c.App.GetSidebarCategoryOrder(c.AppContext, c.Params.UserId, c.Params.TeamId) order, appErr := c.App.GetSidebarCategoryOrder(c.AppContext, c.Params.UserId, c.Params.TeamId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return 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) { 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 return
} }
categories, err := c.App.GetSidebarCategory(c.AppContext, c.Params.CategoryId) categories, appErr := c.App.GetSidebarCategory(c.AppContext, c.Params.CategoryId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
categoriesJSON, jsonErr := json.Marshal(categories) categoriesJSON, err := json.Marshal(categories)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getCategoryForTeamForUser", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getCategoryForTeamForUser", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
@@ -199,9 +202,9 @@ func updateCategoriesForTeamForUser(c *Context, w http.ResponseWriter, r *http.R
return return
} }
categoriesJSON, jsonErr := json.Marshal(categories) categoriesJSON, err := json.Marshal(categories)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("updateCategoriesForTeamForUser", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("updateCategoriesForTeamForUser", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return 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 { 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, IncludeDeleted: true,
LastDeleteAt: 0, LastDeleteAt: 0,
}) })
if err != nil { if appErr != nil {
return model.NewAppError("validateSidebarCategory", "api.invalid_channel", nil, err.Error(), http.StatusBadRequest) return model.NewAppError("validateSidebarCategory", "api.invalid_channel", nil, "", http.StatusBadRequest).Wrap(appErr)
} }
category.Channels = validateSidebarCategoryChannels(c, userId, category.Channels, channels) category.Channels = validateSidebarCategoryChannels(c, userId, category.Channels, channels)
@@ -295,9 +298,9 @@ func updateCategoryForTeamForUser(c *Context, w http.ResponseWriter, r *http.Req
return return
} }
categoryJSON, jsonErr := json.Marshal(categories[0]) categoryJSON, err := json.Marshal(categories[0])
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("updateCategoryForTeamForUser", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("updateCategoryForTeamForUser", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }

Просмотреть файл

@@ -569,7 +569,7 @@ func TestCreateGroupChannel(t *testing.T) {
require.Equal(t, rgc.Id, rgc2.Id, "should have returned existing channel") require.Equal(t, rgc.Id, rgc2.Id, "should have returned existing channel")
m2, _ := th.App.GetChannelMembersPage(th.Context, rgc2.Id, 0, 10) 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}) _, resp, err = client.CreateGroupChannel([]string{user2.Id})
require.Error(t, err) require.Error(t, err)
@@ -3840,7 +3840,7 @@ func TestUpdateChannelScheme(t *testing.T) {
th.App.Srv().SetLicense(nil) th.App.Srv().SetLicense(nil)
resp, err = th.SystemAdminClient.UpdateChannelScheme(channel.Id, channelScheme.Id) resp, err = th.SystemAdminClient.UpdateChannelScheme(channel.Id, channelScheme.Id)
require.Error(t, err) require.Error(t, err)
CheckNotImplementedStatus(t, resp) CheckForbiddenStatus(t, resp)
th.App.Srv().SetLicense(model.NewTestLicense("")) th.App.Srv().SetLicense(model.NewTestLicense(""))
// Test an invalid scheme scope. // Test an invalid scheme scope.

Просмотреть файл

@@ -7,7 +7,7 @@ import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"encoding/json" "encoding/json"
"io/ioutil" "io"
"net/http" "net/http"
"time" "time"
@@ -73,7 +73,7 @@ func handleNotifyAdminToUpgrade(c *Context, w http.ResponseWriter, r *http.Reque
func getSubscription(c *Context, w http.ResponseWriter, r *http.Request) { func getSubscription(c *Context, w http.ResponseWriter, r *http.Request) {
if c.App.Channels().License() == nil || !*c.App.Channels().License().Features.Cloud { 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 return
} }
@@ -105,7 +105,7 @@ func getSubscription(c *Context, w http.ResponseWriter, r *http.Request) {
json, err := json.Marshal(subscription) json, err := json.Marshal(subscription)
if err != nil { 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 return
} }
@@ -123,40 +123,40 @@ func changeSubscription(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
bodyBytes, err := ioutil.ReadAll(r.Body) bodyBytes, err := io.ReadAll(r.Body)
if err != nil { 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 return
} }
var subscriptionChange *model.SubscriptionChange var subscriptionChange *model.SubscriptionChange
if err = json.Unmarshal(bodyBytes, &subscriptionChange); err != nil { 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 return
} }
currentSubscription, appErr := c.App.Cloud().GetSubscription(c.AppContext.Session().UserId) currentSubscription, appErr := c.App.Cloud().GetSubscription(c.AppContext.Session().UserId)
if appErr != nil { 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 return
} }
changedSub, err := c.App.Cloud().ChangeSubscription(c.AppContext.Session().UserId, currentSubscription.ID, subscriptionChange) changedSub, err := c.App.Cloud().ChangeSubscription(c.AppContext.Session().UserId, currentSubscription.ID, subscriptionChange)
if err != nil { 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 return
} }
json, err := json.Marshal(changedSub) json, err := json.Marshal(changedSub)
if err != nil { 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 return
} }
// Log failures for purchase confirmation email, but don't show an error to the user so as not to confuse them // 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. // At this point, the upgrade is complete.
if nErr := c.App.SendUpgradeConfirmationEmail(); nErr != nil { if appErr := c.App.SendUpgradeConfirmationEmail(); appErr != nil {
c.Logger.Error("Error sending purchase confirmation email") c.Logger.Error("Error sending purchase confirmation email", mlog.Err(appErr))
} }
w.Write(json) w.Write(json)
@@ -174,28 +174,28 @@ func requestCloudTrial(c *Context, w http.ResponseWriter, r *http.Request) {
} }
// check if the email needs to be set // check if the email needs to be set
bodyBytes, err := ioutil.ReadAll(r.Body) bodyBytes, err := io.ReadAll(r.Body)
if err != nil { 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 return
} }
// this value will not be empty when both emails (user admin and CWS customer) are not business email and // 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 // we need to request a new email from the user via the request business email modal
var startTrialRequest *model.StartCloudTrialRequest var startTrialRequest *model.StartCloudTrialRequest
if err = json.Unmarshal(bodyBytes, &startTrialRequest); err != nil { 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 return
} }
changedSub, err := c.App.Cloud().RequestCloudTrial(c.AppContext.Session().UserId, startTrialRequest.SubscriptionID, startTrialRequest.Email) changedSub, err := c.App.Cloud().RequestCloudTrial(c.AppContext.Session().UserId, startTrialRequest.SubscriptionID, startTrialRequest.Email)
if err != nil { 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 return
} }
json, err := json.Marshal(changedSub) json, err := json.Marshal(changedSub)
if err != nil { 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 return
} }
@@ -215,36 +215,37 @@ func validateBusinessEmail(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
user, userErr := c.App.GetUser(c.AppContext.Session().UserId) user, appErr := c.App.GetUser(c.AppContext.Session().UserId)
if userErr != nil { if appErr != nil {
c.Err = model.NewAppError("Api4.validateBusinessEmail", "api.cloud.request_error", nil, "", http.StatusInternalServerError) c.Err = model.NewAppError("Api4.validateBusinessEmail", "api.cloud.request_error", nil, "", http.StatusInternalServerError).Wrap(appErr)
return return
} }
bodyBytes, err := ioutil.ReadAll(r.Body) bodyBytes, err := io.ReadAll(r.Body)
if err != nil { 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 return
} }
var emailToValidate *model.ValidateBusinessEmailRequest var emailToValidate *model.ValidateBusinessEmailRequest
if err := json.Unmarshal(bodyBytes, &emailToValidate); err != nil { err = json.Unmarshal(bodyBytes, &emailToValidate)
c.Err = model.NewAppError("Api4.requestCloudTrial", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) if err != nil {
c.Err = model.NewAppError("Api4.requestCloudTrial", "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
emailErr := c.App.Cloud().ValidateBusinessEmail(user.Id, emailToValidate.Email) err = c.App.Cloud().ValidateBusinessEmail(user.Id, emailToValidate.Email)
if emailErr != nil { if err != nil {
c.Err = model.NewAppError("Api4.validateBusinessEmail", "api.cloud.request_error", nil, emailErr.Error(), http.StatusForbidden) c.Err = model.NewAppError("Api4.validateBusinessEmail", "api.cloud.request_error", nil, "", http.StatusForbidden).Wrap(err)
emailResp := model.ValidateBusinessEmailResponse{IsValid: false} emailResp := model.ValidateBusinessEmailResponse{IsValid: false}
if err := json.NewEncoder(w).Encode(emailResp); err != nil { 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 return
} }
emailResp := model.ValidateBusinessEmailResponse{IsValid: true} emailResp := model.ValidateBusinessEmailResponse{IsValid: true}
if err := json.NewEncoder(w).Encode(emailResp); err != nil { 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))
} }
} }
@@ -296,7 +297,7 @@ func validateWorkspaceBusinessEmail(c *Context, w http.ResponseWriter, r *http.R
func getCloudProducts(c *Context, w http.ResponseWriter, r *http.Request) { func getCloudProducts(c *Context, w http.ResponseWriter, r *http.Request) {
if c.App.Channels().License() == nil || !*c.App.Channels().License().Features.Cloud { 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 return
} }
@@ -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) products, err := c.App.Cloud().GetCloudProducts(c.AppContext.Session().UserId, includeLegacyProducts)
if err != nil { 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 return
} }
byteProductsData, err := json.Marshal(products) byteProductsData, err := json.Marshal(products)
if err != nil { 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 return
} }
if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionSysconsoleReadBilling) { if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionSysconsoleReadBilling) {
sanitizedProducts := []model.UserFacingProduct{} sanitizedProducts := []model.UserFacingProduct{}
err = json.Unmarshal(byteProductsData, &sanitizedProducts) err = json.Unmarshal(byteProductsData, &sanitizedProducts)
if err != nil { 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 return
} }
byteSanitizedProductsData, err := json.Marshal(sanitizedProducts) byteSanitizedProductsData, err := json.Marshal(sanitizedProducts)
if err != nil { 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 return
} }
@@ -338,19 +338,19 @@ func getCloudProducts(c *Context, w http.ResponseWriter, r *http.Request) {
func getCloudLimits(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 { 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 return
} }
limits, err := c.App.Cloud().GetCloudLimits(c.AppContext.Session().UserId) limits, err := c.App.Cloud().GetCloudLimits(c.AppContext.Session().UserId)
if err != nil { 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 return
} }
json, err := json.Marshal(limits) json, err := json.Marshal(limits)
if err != nil { 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 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) { func getCloudCustomer(c *Context, w http.ResponseWriter, r *http.Request) {
if c.App.Channels().License() == nil || !*c.App.Channels().License().Features.Cloud { 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 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) customer, err := c.App.Cloud().GetCloudCustomer(c.AppContext.Session().UserId)
if err != nil { 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 return
} }
json, err := json.Marshal(customer) json, err := json.Marshal(customer)
if err != nil { 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 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) { func updateCloudCustomer(c *Context, w http.ResponseWriter, r *http.Request) {
if c.App.Channels().License() == nil || !*c.App.Channels().License().Features.Cloud { 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 return
} }
@@ -394,27 +394,27 @@ func updateCloudCustomer(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
bodyBytes, err := ioutil.ReadAll(r.Body) bodyBytes, err := io.ReadAll(r.Body)
if err != nil { 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 return
} }
var customerInfo *model.CloudCustomerInfo var customerInfo *model.CloudCustomerInfo
if err = json.Unmarshal(bodyBytes, &customerInfo); err != nil { 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 return
} }
customer, appErr := c.App.Cloud().UpdateCloudCustomer(c.AppContext.Session().UserId, customerInfo) customer, appErr := c.App.Cloud().UpdateCloudCustomer(c.AppContext.Session().UserId, customerInfo)
if appErr != nil { 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 return
} }
json, err := json.Marshal(customer) json, err := json.Marshal(customer)
if err != nil { 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 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) { func updateCloudCustomerAddress(c *Context, w http.ResponseWriter, r *http.Request) {
if c.App.Channels().License() == nil || !*c.App.Channels().License().Features.Cloud { 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 return
} }
@@ -432,27 +432,27 @@ func updateCloudCustomerAddress(c *Context, w http.ResponseWriter, r *http.Reque
return return
} }
bodyBytes, err := ioutil.ReadAll(r.Body) bodyBytes, err := io.ReadAll(r.Body)
if err != nil { 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 return
} }
var address *model.Address var address *model.Address
if err = json.Unmarshal(bodyBytes, &address); err != nil { 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 return
} }
customer, appErr := c.App.Cloud().UpdateCloudCustomerAddress(c.AppContext.Session().UserId, address) customer, appErr := c.App.Cloud().UpdateCloudCustomerAddress(c.AppContext.Session().UserId, address)
if appErr != nil { 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 return
} }
json, err := json.Marshal(customer) json, err := json.Marshal(customer)
if err != nil { 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 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) { func createCustomerPayment(c *Context, w http.ResponseWriter, r *http.Request) {
if c.App.Channels().License() == nil || !*c.App.Channels().License().Features.Cloud { 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 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) intent, err := c.App.Cloud().CreateCustomerPayment(c.AppContext.Session().UserId)
if err != nil { 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 return
} }
json, err := json.Marshal(intent) json, err := json.Marshal(intent)
if err != nil { 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 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) { func confirmCustomerPayment(c *Context, w http.ResponseWriter, r *http.Request) {
if c.App.Channels().License() == nil || !*c.App.Channels().License().Features.Cloud { 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 return
} }
@@ -504,21 +504,21 @@ func confirmCustomerPayment(c *Context, w http.ResponseWriter, r *http.Request)
auditRec := c.MakeAuditRecord("confirmCustomerPayment", audit.Fail) auditRec := c.MakeAuditRecord("confirmCustomerPayment", audit.Fail)
defer c.LogAuditRec(auditRec) defer c.LogAuditRec(auditRec)
bodyBytes, err := ioutil.ReadAll(r.Body) bodyBytes, err := io.ReadAll(r.Body)
if err != nil { 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 return
} }
var confirmRequest *model.ConfirmPaymentMethodRequest var confirmRequest *model.ConfirmPaymentMethodRequest
if err = json.Unmarshal(bodyBytes, &confirmRequest); err != nil { 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 return
} }
err = c.App.Cloud().ConfirmCustomerPayment(c.AppContext.Session().UserId, confirmRequest) err = c.App.Cloud().ConfirmCustomerPayment(c.AppContext.Session().UserId, confirmRequest)
if err != nil { 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 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) { func getInvoicesForSubscription(c *Context, w http.ResponseWriter, r *http.Request) {
if c.App.Channels().License() == nil || !*c.App.Channels().License().Features.Cloud { 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 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) invoices, appErr := c.App.Cloud().GetInvoicesForSubscription(c.AppContext.Session().UserId)
if appErr != nil { 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 return
} }
json, err := json.Marshal(invoices) json, err := json.Marshal(invoices)
if err != nil { 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 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) { func getSubscriptionInvoicePDF(c *Context, w http.ResponseWriter, r *http.Request) {
if c.App.Channels().License() == nil || !*c.App.Channels().License().Features.Cloud { 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 return
} }
@@ -590,11 +590,11 @@ func getSubscriptionInvoicePDF(c *Context, w http.ResponseWriter, r *http.Reques
func handleCWSWebhook(c *Context, w http.ResponseWriter, r *http.Request) { func handleCWSWebhook(c *Context, w http.ResponseWriter, r *http.Request) {
if c.App.Channels().License() == nil || !*c.App.Channels().License().Features.Cloud { 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 return
} }
bodyBytes, err := ioutil.ReadAll(r.Body) bodyBytes, err := io.ReadAll(r.Body)
if err != nil { if err != nil {
c.Err = model.NewAppError("Api4.handleCWSWebhook", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("Api4.handleCWSWebhook", "api.cloud.app_error", nil, err.Error(), http.StatusInternalServerError)
return return

Просмотреть файл

@@ -30,7 +30,7 @@ func Test_getCloudLimits(t *testing.T) {
limits, r, err := th.Client.GetProductLimits() limits, r, err := th.Client.GetProductLimits()
require.Error(t, err) require.Error(t, err)
require.Nil(t, limits) 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) { 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() limits, r, err := th.Client.GetProductLimits()
require.Error(t, err) require.Error(t, err)
require.Nil(t, limits) 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) { t.Run("error fetching limits returns internal server error", func(t *testing.T) {

Просмотреть файл

@@ -26,9 +26,9 @@ func getClusterStatus(c *Context, w http.ResponseWriter, r *http.Request) {
} }
infos := c.App.GetClusterStatus() infos := c.App.GetClusterStatus()
js, jsonErr := json.Marshal(infos) js, err := json.Marshal(infos)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getClusterStatus", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getClusterStatus", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(js) w.Write(js)

Просмотреть файл

@@ -417,9 +417,9 @@ func listCommandAutocompleteSuggestions(c *Context, w http.ResponseWriter, r *ht
} }
userInput = strings.TrimPrefix(userInput, "/") userInput = strings.TrimPrefix(userInput, "/")
commands, err := c.App.ListAutocompleteCommands(c.Params.TeamId, c.AppContext.T) commands, appErr := c.App.ListAutocompleteCommands(c.Params.TeamId, c.AppContext.T)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -436,9 +436,9 @@ func listCommandAutocompleteSuggestions(c *Context, w http.ResponseWriter, r *ht
suggestions := c.App.GetSuggestions(c.AppContext, commandArgs, commands, roleId) suggestions := c.App.GetSuggestions(c.AppContext, commandArgs, commands, roleId)
js, jsonErr := json.Marshal(suggestions) js, err := json.Marshal(suggestions)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("listCommandAutocompleteSuggestions", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("listCommandAutocompleteSuggestions", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(js) w.Write(js)

Просмотреть файл

@@ -108,9 +108,10 @@ func configReload(c *Context, w http.ResponseWriter, r *http.Request) {
} }
func updateConfig(c *Context, w http.ResponseWriter, r *http.Request) { func updateConfig(c *Context, w http.ResponseWriter, r *http.Request) {
cfg := model.ConfigFromJSON(r.Body) var cfg *model.Config
if cfg == nil { err := json.NewDecoder(r.Body).Decode(&cfg)
c.SetInvalidParam("config") if err != nil || cfg == nil {
c.SetInvalidParamWithErr("config", err)
return return
} }
@@ -132,14 +133,13 @@ func updateConfig(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
var err1 error cfg, err = config.Merge(appCfg, cfg, &utils.MergeConfig{
cfg, err1 = config.Merge(appCfg, cfg, &utils.MergeConfig{
StructFieldFilter: func(structField reflect.StructField, base, patch reflect.Value) bool { StructFieldFilter: func(structField reflect.StructField, base, patch reflect.Value) bool {
return writeFilter(c, structField) return writeFilter(c, structField)
}, },
}) })
if err1 != nil { if err != nil {
c.Err = model.NewAppError("updateConfig", "api.config.update_config.restricted_merge.app_error", nil, err1.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("updateConfig", "api.config.update_config.restricted_merge.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
@@ -156,8 +156,8 @@ func updateConfig(c *Context, w http.ResponseWriter, r *http.Request) {
*cfg.PluginSettings.MarketplaceURL = *appCfg.PluginSettings.MarketplaceURL *cfg.PluginSettings.MarketplaceURL = *appCfg.PluginSettings.MarketplaceURL
} }
if err := c.App.CheckFreemiumLimitsForConfigSave(appCfg, cfg); err != nil { if appErr := c.App.CheckFreemiumLimitsForConfigSave(appCfg, cfg); appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -173,33 +173,33 @@ func updateConfig(c *Context, w http.ResponseWriter, r *http.Request) {
c.App.HandleMessageExportConfig(cfg, appCfg) c.App.HandleMessageExportConfig(cfg, appCfg)
if err := cfg.IsValid(); err != nil { if appErr := cfg.IsValid(); appErr != nil {
c.Err = err c.Err = appErr
return 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 { if err != nil {
c.Err = err c.Err = model.NewAppError("updateConfig", "api.config.update_config.diff.app_error", nil, "", http.StatusInternalServerError).Wrap(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)
return return
} }
auditRec.AddEventPriorState(&diffs) auditRec.AddEventPriorState(&diffs)
newCfg.Sanitize() 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 { StructFieldFilter: func(structField reflect.StructField, base, patch reflect.Value) bool {
return readFilter(c, structField) return readFilter(c, structField)
}, },
}) })
if mergeErr != nil { if err != nil {
c.Err = model.NewAppError("updateConfig", "api.config.update_config.restricted_merge.app_error", nil, mergeErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("updateConfig", "api.config.update_config.restricted_merge.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
return 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") w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
if c.App.Channels().License() != nil && *c.App.Channels().License().Features.Cloud { if c.App.Channels().License() != nil && *c.App.Channels().License().Features.Cloud {
js, jsonErr := cfg.ToJSONFiltered(model.ConfigAccessTagType, model.ConfigAccessTagCloudRestrictable) js, err := cfg.ToJSONFiltered(model.ConfigAccessTagType, model.ConfigAccessTagCloudRestrictable)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("updateConfig", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("updateConfig", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(js) 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) { func patchConfig(c *Context, w http.ResponseWriter, r *http.Request) {
cfg := model.ConfigFromJSON(r.Body) var cfg *model.Config
if cfg == nil { err := json.NewDecoder(r.Body).Decode(&cfg)
c.SetInvalidParam("config") if err != nil || cfg == nil {
c.SetInvalidParamWithErr("config", err)
return return
} }
@@ -298,8 +299,8 @@ func patchConfig(c *Context, w http.ResponseWriter, r *http.Request) {
} }
} }
if err := c.App.CheckFreemiumLimitsForConfigSave(appCfg, cfg); err != nil { if appErr := c.App.CheckFreemiumLimitsForConfigSave(appCfg, cfg); appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -315,30 +316,29 @@ func patchConfig(c *Context, w http.ResponseWriter, r *http.Request) {
c.App.HandleMessageExportConfig(cfg, appCfg) c.App.HandleMessageExportConfig(cfg, appCfg)
} }
updatedCfg, mergeErr := config.Merge(appCfg, cfg, &utils.MergeConfig{ updatedCfg, err := config.Merge(appCfg, cfg, &utils.MergeConfig{
StructFieldFilter: filterFn, 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 { 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 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 { if err != nil {
c.Err = err c.Err = model.NewAppError("patchConfig", "api.config.patch_config.diff.app_error", nil, "", http.StatusInternalServerError).Wrap(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)
return return
} }
@@ -348,21 +348,21 @@ func patchConfig(c *Context, w http.ResponseWriter, r *http.Request) {
auditRec.Success() 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 { StructFieldFilter: func(structField reflect.StructField, base, patch reflect.Value) bool {
return readFilter(c, structField) return readFilter(c, structField)
}, },
}) })
if mergeErr != nil { if err != nil {
c.Err = model.NewAppError("patchConfig", "api.config.patch_config.restricted_merge.app_error", nil, mergeErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("patchConfig", "api.config.patch_config.restricted_merge.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
if c.App.Channels().License() != nil && *c.App.Channels().License().Features.Cloud { if c.App.Channels().License() != nil && *c.App.Channels().License().Features.Cloud {
js, jsonErr := cfg.ToJSONFiltered(model.ConfigAccessTagType, model.ConfigAccessTagCloudRestrictable) js, err := cfg.ToJSONFiltered(model.ConfigAccessTagType, model.ConfigAccessTagCloudRestrictable)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("patchConfig", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("patchConfig", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(js) w.Write(js)

Просмотреть файл

@@ -35,9 +35,10 @@ func localGetConfig(c *Context, w http.ResponseWriter, r *http.Request) {
} }
func localUpdateConfig(c *Context, w http.ResponseWriter, r *http.Request) { func localUpdateConfig(c *Context, w http.ResponseWriter, r *http.Request) {
cfg := model.ConfigFromJSON(r.Body) var cfg *model.Config
if cfg == nil { err := json.NewDecoder(r.Body).Decode(&cfg)
c.SetInvalidParam("config") if err != nil || cfg == nil {
c.SetInvalidParamWithErr("config", err)
return return
} }
@@ -56,15 +57,15 @@ func localUpdateConfig(c *Context, w http.ResponseWriter, r *http.Request) {
c.App.HandleMessageExportConfig(cfg, appCfg) c.App.HandleMessageExportConfig(cfg, appCfg)
err := cfg.IsValid() appErr := cfg.IsValid()
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
oldCfg, newCfg, err := c.App.SaveConfig(cfg, true) oldCfg, newCfg, appErr := c.App.SaveConfig(cfg, true)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return 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) { func localPatchConfig(c *Context, w http.ResponseWriter, r *http.Request) {
cfg := model.ConfigFromJSON(r.Body) var cfg *model.Config
if cfg == nil { err := json.NewDecoder(r.Body).Decode(&cfg)
c.SetInvalidParam("config") if err != nil || cfg == nil {
c.SetInvalidParamWithErr("config", err)
return return
} }
@@ -114,21 +116,21 @@ func localPatchConfig(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
err := updatedCfg.IsValid() appErr := updatedCfg.IsValid()
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
oldCfg, newCfg, err := c.App.SaveConfig(updatedCfg, true) oldCfg, newCfg, appErr := c.App.SaveConfig(updatedCfg, true)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
diffs, diffErr := config.Diff(oldCfg, newCfg) diffs, err := config.Diff(oldCfg, newCfg)
if diffErr != nil { if err != 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 return
} }
auditRec.AddEventPriorState(&diffs) auditRec.AddEventPriorState(&diffs)

Просмотреть файл

@@ -6,7 +6,7 @@ package api4
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil" "io"
"net/http" "net/http"
"os" "os"
"strings" "strings"
@@ -533,7 +533,7 @@ func TestUpdateConfigRestrictSystemAdmin(t *testing.T) {
} }
func TestUpdateConfigDiffInAuditRecord(t *testing.T) { func TestUpdateConfigDiffInAuditRecord(t *testing.T) {
logFile, err := ioutil.TempFile("", "adv.log") logFile, err := os.CreateTemp("", "adv.log")
require.NoError(t, err) require.NoError(t, err)
defer os.Remove(logFile.Name()) defer os.Remove(logFile.Name())
@@ -569,7 +569,7 @@ func TestUpdateConfigDiffInAuditRecord(t *testing.T) {
require.NoError(t, logFile.Sync()) require.NoError(t, logFile.Sync())
data, err := ioutil.ReadAll(logFile) data, err := io.ReadAll(logFile)
require.NoError(t, err) require.NoError(t, err)
require.NotEmpty(t, data) require.NotEmpty(t, data)
@@ -955,7 +955,7 @@ func TestMigrateConfig(t *testing.T) {
file, err := json.MarshalIndent(cfg, "", " ") file, err := json.MarshalIndent(cfg, "", " ")
require.NoError(t, err) require.NoError(t, err)
err = ioutil.WriteFile("from.json", file, 0644) err = os.WriteFile("from.json", file, 0644)
require.NoError(t, err) require.NoError(t, err)
defer os.Remove("from.json") defer os.Remove("from.json")

Просмотреть файл

@@ -9,6 +9,7 @@ import (
"github.com/mattermost/mattermost-server/v6/audit" "github.com/mattermost/mattermost-server/v6/audit"
"github.com/mattermost/mattermost-server/v6/model" "github.com/mattermost/mattermost-server/v6/model"
"github.com/mattermost/mattermost-server/v6/shared/mlog"
) )
func (api *API) InitDataRetention() { func (api *API) InitDataRetention() {
@@ -34,15 +35,15 @@ func (api *API) InitDataRetention() {
func getGlobalPolicy(c *Context, w http.ResponseWriter, r *http.Request) { func getGlobalPolicy(c *Context, w http.ResponseWriter, r *http.Request) {
// No permission check required. // No permission check required.
policy, err := c.App.GetGlobalRetentionPolicy() policy, appErr := c.App.GetGlobalRetentionPolicy()
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(policy) js, err := json.Marshal(policy)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getGlobalPolicy", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getGlobalPolicy", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(js) w.Write(js)
@@ -57,15 +58,15 @@ func getPolicies(c *Context, w http.ResponseWriter, r *http.Request) {
limit := c.Params.PerPage limit := c.Params.PerPage
offset := c.Params.Page * limit offset := c.Params.Page * limit
policies, err := c.App.GetRetentionPolicies(offset, limit) policies, appErr := c.App.GetRetentionPolicies(offset, limit)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(policies) js, err := json.Marshal(policies)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getPolicies", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getPolicies", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(js) w.Write(js)
@@ -77,14 +78,19 @@ func getPoliciesCount(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
count, err := c.App.GetRetentionPoliciesCount() count, appErr := c.App.GetRetentionPoliciesCount()
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
body := map[string]int64{"total_count": count}
b, _ := json.Marshal(body) body := struct {
w.Write(b) 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) { 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() c.RequirePolicyId()
policy, err := c.App.GetRetentionPolicy(c.Params.PolicyId) policy, appErr := c.App.GetRetentionPolicy(c.Params.PolicyId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(policy) js, err := json.Marshal(policy)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getPolicy", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getPolicy", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(js) w.Write(js)
@@ -123,17 +129,17 @@ func createPolicy(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
newPolicy, err := c.App.CreateRetentionPolicy(&policy) newPolicy, appErr := c.App.CreateRetentionPolicy(&policy)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
auditRec.AddEventResultState(newPolicy) auditRec.AddEventResultState(newPolicy)
auditRec.AddEventObjectType("policy") auditRec.AddEventObjectType("policy")
js, jsonErr := json.Marshal(newPolicy) js, err := json.Marshal(newPolicy)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("createPolicy", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("createPolicy", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
auditRec.Success() auditRec.Success()
@@ -159,18 +165,18 @@ func patchPolicy(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
policy, err := c.App.PatchRetentionPolicy(&patch) policy, appErr := c.App.PatchRetentionPolicy(&patch)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
auditRec.AddEventResultState(policy) auditRec.AddEventResultState(policy)
auditRec.AddEventObjectType("retention_policy") auditRec.AddEventObjectType("retention_policy")
js, jsonErr := json.Marshal(policy) js, err := json.Marshal(policy)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("patchPolicy", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("patchPolicy", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
auditRec.Success() auditRec.Success()
@@ -209,15 +215,15 @@ func getTeamsForPolicy(c *Context, w http.ResponseWriter, r *http.Request) {
limit := c.Params.PerPage limit := c.Params.PerPage
offset := c.Params.Page * limit offset := c.Params.Page * limit
teams, err := c.App.GetTeamsForRetentionPolicy(policyId, offset, limit) teams, appErr := c.App.GetTeamsForRetentionPolicy(policyId, offset, limit)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
b, jsonErr := json.Marshal(teams) b, err := json.Marshal(teams)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("Api4.getTeamsForPolicy", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("Api4.getTeamsForPolicy", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(b) w.Write(b)
@@ -232,24 +238,24 @@ func searchTeamsInPolicy(c *Context, w http.ResponseWriter, r *http.Request) {
} }
var props model.TeamSearch var props model.TeamSearch
if jsonErr := json.NewDecoder(r.Body).Decode(&props); jsonErr != nil { if err := json.NewDecoder(r.Body).Decode(&props); err != nil {
c.SetInvalidParamWithErr("team_search", jsonErr) c.SetInvalidParamWithErr("team_search", err)
return return
} }
props.PolicyID = model.NewString(c.Params.PolicyId) props.PolicyID = model.NewString(c.Params.PolicyId)
props.IncludePolicyID = model.NewBool(true) props.IncludePolicyID = model.NewBool(true)
teams, _, err := c.App.SearchAllTeams(&props) teams, _, appErr := c.App.SearchAllTeams(&props)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
c.App.SanitizeTeams(*c.AppContext.Session(), teams) c.App.SanitizeTeams(*c.AppContext.Session(), teams)
js, jsonErr := json.Marshal(teams) js, err := json.Marshal(teams)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("searchTeamsInPolicy", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("searchTeamsInPolicy", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(js) w.Write(js)
@@ -323,15 +329,15 @@ func getChannelsForPolicy(c *Context, w http.ResponseWriter, r *http.Request) {
limit := c.Params.PerPage limit := c.Params.PerPage
offset := c.Params.Page * limit offset := c.Params.Page * limit
channels, err := c.App.GetChannelsForRetentionPolicy(policyId, offset, limit) channels, appErr := c.App.GetChannelsForRetentionPolicy(policyId, offset, limit)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
b, jsonErr := json.Marshal(channels) b, err := json.Marshal(channels)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("Api4.getChannelsForPolicy", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("Api4.getChannelsForPolicy", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(b) w.Write(b)

Просмотреть файл

@@ -4,10 +4,12 @@
package api4 package api4
import ( import (
"encoding/json"
"net/http" "net/http"
"github.com/mattermost/mattermost-server/v6/audit" "github.com/mattermost/mattermost-server/v6/audit"
"github.com/mattermost/mattermost-server/v6/model" "github.com/mattermost/mattermost-server/v6/model"
"github.com/mattermost/mattermost-server/v6/shared/mlog"
) )
func (api *API) InitElasticsearch() { func (api *API) InitElasticsearch() {
@@ -16,7 +18,11 @@ func (api *API) InitElasticsearch() {
} }
func testElasticsearch(c *Context, w http.ResponseWriter, r *http.Request) { 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 { if cfg == nil {
cfg = c.App.Config() cfg = c.App.Config()
} }

Просмотреть файл

@@ -7,7 +7,6 @@ import (
"bytes" "bytes"
"image" "image"
_ "image/gif" _ "image/gif"
"io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"testing" "testing"
@@ -100,7 +99,7 @@ func TestCreateEmoji(t *testing.T) {
} }
path, _ := fileutils.FindDir("tests") 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) require.NoError(t, err)
newEmoji, _, err = client.CreateEmoji(emoji, bytes, "image.webp") newEmoji, _, err = client.CreateEmoji(emoji, bytes, "image.webp")
require.NoError(t, err) require.NoError(t, err)

Просмотреть файл

@@ -33,7 +33,7 @@ func listExports(c *Context, w http.ResponseWriter, r *http.Request) {
data, err := json.Marshal(exports) data, err := json.Marshal(exports)
if err != nil { 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 return
} }

Просмотреть файл

@@ -6,7 +6,6 @@ package api4
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"testing" "testing"
@@ -151,7 +150,7 @@ func TestDownloadExport(t *testing.T) {
data := randomBytes(t, 1024*1024) data := randomBytes(t, 1024*1024)
var buf bytes.Buffer var buf bytes.Buffer
exportName := "export.zip" 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) require.NoError(t, err)
n, _, err := c.DownloadExport(exportName, &buf, 0) n, _, err := c.DownloadExport(exportName, &buf, 0)
@@ -168,7 +167,7 @@ func TestDownloadExport(t *testing.T) {
data := randomBytes(t, 1024*1024) data := randomBytes(t, 1024*1024)
var buf bytes.Buffer var buf bytes.Buffer
exportName := "export.zip" 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) require.NoError(t, err)
offset := 1024 * 512 offset := 1024 * 512

Просмотреть файл

@@ -103,7 +103,7 @@ func uploadFileStream(c *Context, w http.ResponseWriter, r *http.Request) {
if !*c.App.Config().FileSettings.EnableFileAttachments { if !*c.App.Config().FileSettings.EnableFileAttachments {
c.Err = model.NewAppError("uploadFileStream", c.Err = model.NewAppError("uploadFileStream",
"api.file.attachments.disabled.app_error", "api.file.attachments.disabled.app_error",
nil, "", http.StatusNotImplemented) nil, "", http.StatusForbidden)
return return
} }
@@ -545,7 +545,7 @@ func getFileLink(c *Context, w http.ResponseWriter, r *http.Request) {
} }
if !*c.App.Config().FileSettings.EnablePublicLink { 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 return
} }
@@ -643,7 +643,7 @@ func getPublicFile(c *Context, w http.ResponseWriter, r *http.Request) {
} }
if !*c.App.Config().FileSettings.EnablePublicLink { 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 return
} }

Просмотреть файл

@@ -9,7 +9,6 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"mime/multipart" "mime/multipart"
"net/http" "net/http"
"net/textproto" "net/textproto"
@@ -55,7 +54,7 @@ func fileBytes(t *testing.T, path string) []byte {
f, err := os.Open(path) f, err := os.Open(path)
require.NoError(t, err) require.NoError(t, err)
defer f.Close() defer f.Close()
bb, err := ioutil.ReadAll(f) bb, err := io.ReadAll(f)
require.NoError(t, err) require.NoError(t, err)
return bb return bb
} }
@@ -512,7 +511,7 @@ func TestUploadFiles(t *testing.T) {
client: th.SystemAdminClient, client: th.SystemAdminClient,
names: []string{"test.png"}, names: []string{"test.png"},
skipSuccessValidation: true, skipSuccessValidation: true,
checkResponse: CheckNotImplementedStatus, checkResponse: CheckForbiddenStatus,
setupConfig: func(a *app.App) func(a *app.App) { setupConfig: func(a *app.App) func(a *app.App) {
enableFileAttachments := *a.Config().FileSettings.EnableFileAttachments enableFileAttachments := *a.Config().FileSettings.EnableFileAttachments
a.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.EnableFileAttachments = false }) a.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.EnableFileAttachments = false })
@@ -701,10 +700,10 @@ func TestUploadFiles(t *testing.T) {
data, _, err := get(ri.Id) data, _, err := get(ri.Id)
require.NoError(t, err) require.NoError(t, err)
expected, err := ioutil.ReadFile(filepath.Join(testDir, name)) expected, err := os.ReadFile(filepath.Join(testDir, name))
require.NoError(t, err) require.NoError(t, err)
if !bytes.Equal(data, expected) { 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) require.NoError(t, err)
defer tf.Close() defer tf.Close()
_, err = io.Copy(tf, bytes.NewReader(data)) _, err = io.Copy(tf, bytes.NewReader(data))
@@ -919,7 +918,7 @@ func TestGetFileLink(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.EnablePublicLink = false }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.EnablePublicLink = false })
_, resp, err = client.GetFileLink(fileId) _, resp, err = client.GetFileLink(fileId)
require.Error(t, err) require.Error(t, err)
CheckNotImplementedStatus(t, resp) CheckForbiddenStatus(t, resp)
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.EnablePublicLink = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.EnablePublicLink = true })
link, _, err := client.GetFileLink(fileId) link, _, err := client.GetFileLink(fileId)
@@ -1090,7 +1089,7 @@ func TestGetPublicFile(t *testing.T) {
resp, err = http.Get(link) resp, err = http.Get(link)
require.NoError(t, err) 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 // test after the salt has changed
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.EnablePublicLink = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.EnablePublicLink = true })

Просмотреть файл

@@ -6,7 +6,7 @@ package api4
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil" "io"
"net/http" "net/http"
"strconv" "strconv"
"strings" "strings"
@@ -99,11 +99,11 @@ func getGroup(c *Context, w http.ResponseWriter, r *http.Request) {
return 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, IncludeMemberCount: c.Params.IncludeMemberCount,
}) })
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -114,15 +114,15 @@ func getGroup(c *Context, w http.ResponseWriter, r *http.Request) {
} }
} }
if lcErr := licensedAndConfiguredForGroupBySource(c.App, group.Source); lcErr != nil { if appErr := licensedAndConfiguredForGroupBySource(c.App, group.Source); appErr != nil {
lcErr.Where = "Api4.getGroup" appErr.Where = "Api4.getGroup"
c.Err = lcErr c.Err = appErr
return return
} }
b, marshalErr := json.Marshal(group) b, err := json.Marshal(group)
if marshalErr != nil { if err != nil {
c.Err = model.NewAppError("Api4.getGroup", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("Api4.getGroup", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
@@ -131,19 +131,19 @@ func getGroup(c *Context, w http.ResponseWriter, r *http.Request) {
func createGroup(c *Context, w http.ResponseWriter, r *http.Request) { func createGroup(c *Context, w http.ResponseWriter, r *http.Request) {
var group *model.GroupWithUserIds var group *model.GroupWithUserIds
if jsonErr := json.NewDecoder(r.Body).Decode(&group); jsonErr != nil { if err := json.NewDecoder(r.Body).Decode(&group); err != nil {
c.SetInvalidParamWithErr("group", jsonErr) c.SetInvalidParamWithErr("group", err)
return return
} }
if group.Source != model.GroupSourceCustom { 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 return
} }
if lcErr := licensedAndConfiguredForGroupBySource(c.App, group.Source); lcErr != nil { if appErr := licensedAndConfiguredForGroupBySource(c.App, group.Source); appErr != nil {
lcErr.Where = "Api4.createGroup" appErr.Where = "Api4.createGroup"
c.Err = lcErr c.Err = appErr
return return
} }
@@ -153,12 +153,12 @@ func createGroup(c *Context, w http.ResponseWriter, r *http.Request) {
} }
if !group.AllowReference { 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 return
} }
if group.GetRemoteId() != "" { 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 return
} }
@@ -166,17 +166,17 @@ func createGroup(c *Context, w http.ResponseWriter, r *http.Request) {
defer c.LogAuditRec(auditRec) defer c.LogAuditRec(auditRec)
auditRec.AddEventParameter("group", group) auditRec.AddEventParameter("group", group)
newGroup, err := c.App.CreateGroupWithUserIds(group) newGroup, appErr := c.App.CreateGroupWithUserIds(group)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
auditRec.AddEventResultState(newGroup) auditRec.AddEventResultState(newGroup)
auditRec.AddEventObjectType("group") auditRec.AddEventObjectType("group")
js, jsonErr := json.Marshal(newGroup) js, err := json.Marshal(newGroup)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("createGroup", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("createGroup", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
auditRec.Success() auditRec.Success()
@@ -190,15 +190,16 @@ func patchGroup(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
group, err := c.App.GetGroup(c.Params.GroupId, nil) group, appErr := c.App.GetGroup(c.Params.GroupId, nil)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
if lcErr := licensedAndConfiguredForGroupBySource(c.App, group.Source); lcErr != nil { appErr = licensedAndConfiguredForGroupBySource(c.App, group.Source)
lcErr.Where = "Api4.patchGroup" if appErr != nil {
c.Err = lcErr appErr.Where = "Api4.patchGroup"
c.Err = appErr
return return
} }
@@ -214,8 +215,8 @@ func patchGroup(c *Context, w http.ResponseWriter, r *http.Request) {
} }
var groupPatch model.GroupPatch var groupPatch model.GroupPatch
if jsonErr := json.NewDecoder(r.Body).Decode(&groupPatch); jsonErr != nil { if err := json.NewDecoder(r.Body).Decode(&groupPatch); err != nil {
c.SetInvalidParamWithErr("group", jsonErr) c.SetInvalidParamWithErr("group", err)
return return
} }
@@ -234,13 +235,13 @@ func patchGroup(c *Context, w http.ResponseWriter, r *http.Request) {
groupPatch.Name = &tmp groupPatch.Name = &tmp
} else { } else {
if *groupPatch.Name == model.UserNotifyAll || *groupPatch.Name == model.ChannelMentionsNotifyProp || *groupPatch.Name == model.UserNotifyHere { 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 return
} }
//check if a user already has this group name //check if a user already has this group name
user, _ := c.App.GetUserByUsername(*groupPatch.Name) user, _ := c.App.GetUserByUsername(*groupPatch.Name)
if user != nil { 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 return
} }
//check if a mentionable group already has this name //check if a mentionable group already has this name
@@ -249,7 +250,7 @@ func patchGroup(c *Context, w http.ResponseWriter, r *http.Request) {
} }
existingGroup, _ := c.App.GetGroupByName(*groupPatch.Name, searchOpts) existingGroup, _ := c.App.GetGroupByName(*groupPatch.Name, searchOpts)
if existingGroup != nil { 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 return
} }
} }
@@ -257,17 +258,17 @@ func patchGroup(c *Context, w http.ResponseWriter, r *http.Request) {
group.Patch(&groupPatch) group.Patch(&groupPatch)
group, err = c.App.UpdateGroup(group) group, appErr = c.App.UpdateGroup(group)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
auditRec.AddEventResultState(group) auditRec.AddEventResultState(group)
auditRec.AddEventObjectType("group") auditRec.AddEventObjectType("group")
b, marshalErr := json.Marshal(group) b, err := json.Marshal(group)
if marshalErr != nil { if err != nil {
c.Err = model.NewAppError("Api4.patchGroup", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("Api4.patchGroup", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
@@ -293,15 +294,15 @@ func linkGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) {
} }
syncableType := c.Params.SyncableType syncableType := c.Params.SyncableType
body, err := ioutil.ReadAll(r.Body) body, err := io.ReadAll(r.Body)
if err != nil { 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 return
} }
group, groupErr := c.App.GetGroup(c.Params.GroupId, nil) group, appErr := c.App.GetGroup(c.Params.GroupId, nil)
if groupErr != nil { if appErr != nil {
c.Err = groupErr c.Err = appErr
return return
} }
@@ -319,18 +320,18 @@ func linkGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) {
var patch *model.GroupSyncablePatch var patch *model.GroupSyncablePatch
err = json.Unmarshal(body, &patch) err = json.Unmarshal(body, &patch)
if err != nil || patch == nil { if err != nil || patch == nil {
c.SetInvalidParam(fmt.Sprintf("Group%s", syncableType.String())) c.SetInvalidParamWithErr(fmt.Sprintf("Group%s", syncableType), err)
return return
} }
auditRec.AddEventParameter("patch", patch) auditRec.AddEventParameter("patch", patch)
if !*c.App.Channels().License().Features.LDAPGroups { 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 return
} }
appErr := verifyLinkUnlinkPermission(c, syncableType, syncableID) appErr = verifyLinkUnlinkPermission(c, syncableType, syncableID)
if appErr != nil { if appErr != nil {
c.Err = appErr c.Err = appErr
return return
@@ -357,9 +358,9 @@ func linkGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusCreated) w.WriteHeader(http.StatusCreated)
b, marshalErr := json.Marshal(groupSyncable) b, err := json.Marshal(groupSyncable)
if marshalErr != nil { if err != nil {
c.Err = model.NewAppError("Api4.createGroupSyncable", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("Api4.createGroupSyncable", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
auditRec.Success() auditRec.Success()
@@ -385,7 +386,7 @@ func getGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) {
syncableType := c.Params.SyncableType syncableType := c.Params.SyncableType
if !*c.App.Channels().License().Features.LDAPGroups { 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 return
} }
@@ -394,15 +395,15 @@ func getGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
groupSyncable, err := c.App.GetGroupSyncable(c.Params.GroupId, syncableID, syncableType) groupSyncable, appErr := c.App.GetGroupSyncable(c.Params.GroupId, syncableID, syncableType)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
b, marshalErr := json.Marshal(groupSyncable) b, err := json.Marshal(groupSyncable)
if marshalErr != nil { if err != nil {
c.Err = model.NewAppError("Api4.getGroupSyncable", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("Api4.getGroupSyncable", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
@@ -422,7 +423,7 @@ func getGroupSyncables(c *Context, w http.ResponseWriter, r *http.Request) {
syncableType := c.Params.SyncableType syncableType := c.Params.SyncableType
if !*c.App.Channels().License().Features.LDAPGroups { 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 return
} }
@@ -431,15 +432,15 @@ func getGroupSyncables(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
groupSyncables, err := c.App.GetGroupSyncables(c.Params.GroupId, syncableType) groupSyncables, appErr := c.App.GetGroupSyncables(c.Params.GroupId, syncableType)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
b, marshalErr := json.Marshal(groupSyncables) b, err := json.Marshal(groupSyncables)
if marshalErr != nil { if err != nil {
c.Err = model.NewAppError("Api4.getGroupSyncables", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("Api4.getGroupSyncables", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
@@ -464,9 +465,9 @@ func patchGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) {
} }
syncableType := c.Params.SyncableType syncableType := c.Params.SyncableType
body, err := ioutil.ReadAll(r.Body) body, err := io.ReadAll(r.Body)
if err != nil { 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 return
} }
@@ -479,7 +480,7 @@ func patchGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) {
var patch *model.GroupSyncablePatch var patch *model.GroupSyncablePatch
err = json.Unmarshal(body, &patch) err = json.Unmarshal(body, &patch)
if err != nil || patch == nil { if err != nil || patch == nil {
c.SetInvalidParam(fmt.Sprintf("Group[%s]Patch", syncableType.String())) c.SetInvalidParamWithErr(fmt.Sprintf("Group[%s]Patch", syncableType), err)
return return
} }
@@ -487,7 +488,7 @@ func patchGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) {
if !*c.App.Channels().License().Features.LDAPGroups { if !*c.App.Channels().License().Features.LDAPGroups {
c.Err = model.NewAppError("Api4.patchGroupSyncable", "api.ldap_groups.license_error", nil, "", c.Err = model.NewAppError("Api4.patchGroupSyncable", "api.ldap_groups.license_error", nil, "",
http.StatusNotImplemented) http.StatusForbidden)
return return
} }
@@ -518,9 +519,9 @@ func patchGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) {
c.App.SyncRolesAndMembership(c.AppContext, syncableID, syncableType, false) c.App.SyncRolesAndMembership(c.AppContext, syncableID, syncableType, false)
}) })
b, marshalErr := json.Marshal(groupSyncable) b, err := json.Marshal(groupSyncable)
if marshalErr != nil { if err != nil {
c.Err = model.NewAppError("Api4.patchGroupSyncable", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("Api4.patchGroupSyncable", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
auditRec.Success() auditRec.Success()
@@ -552,19 +553,19 @@ func unlinkGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) {
auditRec.AddEventParameter("syncable_type", syncableType) auditRec.AddEventParameter("syncable_type", syncableType)
if !*c.App.Channels().License().Features.LDAPGroups { 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 return
} }
err := verifyLinkUnlinkPermission(c, syncableType, syncableID) appErr := verifyLinkUnlinkPermission(c, syncableType, syncableID)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
_, err = c.App.DeleteGroupSyncable(c.Params.GroupId, syncableID, syncableType) _, appErr = c.App.DeleteGroupSyncable(c.Params.GroupId, syncableID, syncableType)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -610,15 +611,16 @@ func getGroupMembers(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
group, err := c.App.GetGroup(c.Params.GroupId, nil) group, appErr := c.App.GetGroup(c.Params.GroupId, nil)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
if lcErr := licensedAndConfiguredForGroupBySource(c.App, group.Source); lcErr != nil { appErr = licensedAndConfiguredForGroupBySource(c.App, group.Source)
lcErr.Where = "Api4.getGroupMembers" if appErr != nil {
c.Err = lcErr appErr.Where = "Api4.getGroupMembers"
c.Err = appErr
return return
} }
@@ -627,21 +629,21 @@ func getGroupMembers(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
members, count, err := c.App.GetGroupMemberUsersPage(c.Params.GroupId, c.Params.Page, c.Params.PerPage) members, count, appErr := c.App.GetGroupMemberUsersPage(c.Params.GroupId, c.Params.Page, c.Params.PerPage)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
b, marshalErr := json.Marshal(struct { b, err := json.Marshal(struct {
Members []*model.User `json:"members"` Members []*model.User `json:"members"`
Count int `json:"total_member_count"` Count int `json:"total_member_count"`
}{ }{
Members: members, Members: members,
Count: count, Count: count,
}) })
if marshalErr != nil { if err != nil {
c.Err = model.NewAppError("Api4.getGroupMembers", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("Api4.getGroupMembers", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
@@ -655,7 +657,7 @@ func getGroupStats(c *Context, w http.ResponseWriter, r *http.Request) {
} }
if !*c.App.Channels().License().Features.LDAPGroups { 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 return
} }
@@ -665,18 +667,18 @@ func getGroupStats(c *Context, w http.ResponseWriter, r *http.Request) {
} }
groupID := c.Params.GroupId groupID := c.Params.GroupId
count, err := c.App.GetGroupMemberCount(groupID) count, appErr := c.App.GetGroupMemberCount(groupID)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
b, marshalErr := json.Marshal(model.GroupStats{ b, err := json.Marshal(model.GroupStats{
GroupID: groupID, GroupID: groupID,
TotalMemberCount: count, TotalMemberCount: count,
}) })
if marshalErr != nil { if err != nil {
c.Err = model.NewAppError("Api4.getGroupStats", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("Api4.getGroupStats", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
@@ -695,19 +697,19 @@ func getGroupsByUserId(c *Context, w http.ResponseWriter, r *http.Request) {
} }
if !*c.App.Channels().License().Features.LDAPGroups { 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 return
} }
groups, err := c.App.GetGroupsByUserId(c.Params.UserId) groups, appErr := c.App.GetGroupsByUserId(c.Params.UserId)
if appErr != nil {
c.Err = appErr
return
}
b, err := json.Marshal(groups)
if err != nil { if err != nil {
c.Err = err c.Err = model.NewAppError("Api4.getGroupsByUserId", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return
}
b, marshalErr := json.Marshal(groups)
if marshalErr != nil {
c.Err = model.NewAppError("Api4.getGroupsByUserId", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError)
return return
} }
@@ -721,15 +723,16 @@ func getGroupsByChannel(c *Context, w http.ResponseWriter, r *http.Request) {
} }
if c.App.Channels().License() == nil || !*c.App.Channels().License().Features.LDAPGroups { 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 return
} }
channel, err := c.App.GetChannel(c.AppContext, c.Params.ChannelId) channel, appErr := c.App.GetChannel(c.AppContext, c.Params.ChannelId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
var permission *model.Permission var permission *model.Permission
if channel.Type == model.ChannelTypePrivate { if channel.Type == model.ChannelTypePrivate {
permission = model.PermissionReadPrivateChannelGroups 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} opts.PageOpts = &model.PageOpts{Page: c.Params.Page, PerPage: c.Params.PerPage}
} }
groups, totalCount, err := c.App.GetGroupsByChannel(c.Params.ChannelId, opts) groups, totalCount, appErr := c.App.GetGroupsByChannel(c.Params.ChannelId, opts)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
b, marshalErr := json.Marshal(struct { b, err := json.Marshal(struct {
Groups []*model.GroupWithSchemeAdmin `json:"groups"` Groups []*model.GroupWithSchemeAdmin `json:"groups"`
Count int `json:"total_group_count"` Count int `json:"total_group_count"`
}{ }{
Groups: groups, Groups: groups,
Count: totalCount, Count: totalCount,
}) })
if err != nil {
if marshalErr != nil { c.Err = model.NewAppError("Api4.getGroupsByChannel", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
c.Err = model.NewAppError("Api4.getGroupsByChannel", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError)
return return
} }
@@ -778,7 +780,7 @@ func getGroupsByTeam(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
if c.App.Channels().License() == nil || !*c.App.Channels().License().Features.LDAPGroups { 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 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} opts.PageOpts = &model.PageOpts{Page: c.Params.Page, PerPage: c.Params.PerPage}
} }
groups, totalCount, err := c.App.GetGroupsByTeam(c.Params.TeamId, opts) groups, totalCount, appErr := c.App.GetGroupsByTeam(c.Params.TeamId, opts)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
b, marshalErr := json.Marshal(struct { b, err := json.Marshal(struct {
Groups []*model.GroupWithSchemeAdmin `json:"groups"` Groups []*model.GroupWithSchemeAdmin `json:"groups"`
Count int `json:"total_group_count"` Count int `json:"total_group_count"`
}{ }{
@@ -805,8 +807,8 @@ func getGroupsByTeam(c *Context, w http.ResponseWriter, r *http.Request) {
Count: totalCount, Count: totalCount,
}) })
if marshalErr != nil { if err != nil {
c.Err = model.NewAppError("Api4.getGroupsByTeam", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("Api4.getGroupsByTeam", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
@@ -820,7 +822,7 @@ func getGroupsAssociatedToChannelsByTeam(c *Context, w http.ResponseWriter, r *h
} }
if !*c.App.Channels().License().Features.LDAPGroups { 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 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} opts.PageOpts = &model.PageOpts{Page: c.Params.Page, PerPage: c.Params.PerPage}
} }
groupsAssociatedByChannelID, err := c.App.GetGroupsAssociatedToChannelsByTeam(c.Params.TeamId, opts) groupsAssociatedByChannelID, appErr := c.App.GetGroupsAssociatedToChannelsByTeam(c.Params.TeamId, opts)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
b, marshalErr := json.Marshal(struct { b, err := json.Marshal(struct {
GroupsAssociatedToChannels map[string][]*model.GroupWithSchemeAdmin `json:"groups"` GroupsAssociatedToChannels map[string][]*model.GroupWithSchemeAdmin `json:"groups"`
}{ }{
GroupsAssociatedToChannels: groupsAssociatedByChannelID, GroupsAssociatedToChannels: groupsAssociatedByChannelID,
}) })
if err != nil {
if marshalErr != nil { c.Err = model.NewAppError("Api4.getGroupsAssociatedToChannelsByTeam", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
c.Err = model.NewAppError("Api4.getGroupsAssociatedToChannelsByTeam", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError)
return 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 they specify the group_source as custom when the feature is disabled, throw an error
if lcErr := licensedAndConfiguredForGroupBySource(c.App, source); lcErr != nil { if appErr := licensedAndConfiguredForGroupBySource(c.App, source); appErr != nil {
lcErr.Where = "Api4.getGroups" appErr.Where = "Api4.getGroups"
c.Err = lcErr c.Err = appErr
return return
} }
@@ -888,9 +889,9 @@ func getGroups(c *Context, w http.ResponseWriter, r *http.Request) {
} }
if teamID != "" { if teamID != "" {
_, err := c.App.GetTeam(teamID) _, appErr := c.App.GetTeam(teamID)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -898,9 +899,9 @@ func getGroups(c *Context, w http.ResponseWriter, r *http.Request) {
} }
if channelID != "" { if channelID != "" {
channel, err := c.App.GetChannel(c.AppContext, channelID) channel, appErr := c.App.GetChannel(c.AppContext, channelID)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
var permission *model.Permission var permission *model.Permission
@@ -918,39 +919,41 @@ func getGroups(c *Context, w http.ResponseWriter, r *http.Request) {
sinceString := r.URL.Query().Get("since") sinceString := r.URL.Query().Get("since")
if sinceString != "" { if sinceString != "" {
since, parseError := strconv.ParseInt(sinceString, 10, 64) since, err := strconv.ParseInt(sinceString, 10, 64)
if parseError != nil { if err != nil {
c.SetInvalidParam("since") c.SetInvalidParamWithErr("since", err)
return return
} }
opts.Since = since opts.Since = since
} }
groups, err := c.App.GetGroups(c.Params.Page, c.Params.PerPage, opts) groups, appErr := c.App.GetGroups(c.Params.Page, c.Params.PerPage, opts)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
var b []byte var (
var marshalErr error b []byte
err error
)
if c.Params.IncludeTotalCount { if c.Params.IncludeTotalCount {
totalCount, countErr := c.App.Srv().Store.Group().GroupCount() totalCount, cerr := c.App.Srv().Store.Group().GroupCount()
if countErr != nil { if cerr != nil {
c.Err = model.NewAppError("Api4.getGroups", "api.custom_groups.count_err", nil, countErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("Api4.getGroups", "api.custom_groups.count_err", nil, "", http.StatusInternalServerError).Wrap(cerr)
return return
} }
gwc := &model.GroupsWithCount{ gwc := &model.GroupsWithCount{
Groups: groups, Groups: groups,
TotalCount: totalCount, TotalCount: totalCount,
} }
b, marshalErr = json.Marshal(gwc) b, err = json.Marshal(gwc)
} else { } else {
b, marshalErr = json.Marshal(groups) b, err = json.Marshal(groups)
} }
if marshalErr != nil { if err != nil {
c.Err = model.NewAppError("Api4.getGroups", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("Api4.getGroups", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
@@ -970,7 +973,7 @@ func deleteGroup(c *Context, w http.ResponseWriter, r *http.Request) {
} }
if group.Source != model.GroupSourceCustom { 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 return
} }
@@ -1006,20 +1009,21 @@ func addGroupMembers(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
group, err := c.App.GetGroup(c.Params.GroupId, nil) group, appErr := c.App.GetGroup(c.Params.GroupId, nil)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
if group.Source != model.GroupSourceCustom { 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 return
} }
if lcErr := licensedAndConfiguredForGroupBySource(c.App, model.GroupSourceCustom); lcErr != nil { appErr = licensedAndConfiguredForGroupBySource(c.App, model.GroupSourceCustom)
lcErr.Where = "Api4.deleteGroup" if appErr != nil {
c.Err = lcErr appErr.Where = "Api4.deleteGroup"
c.Err = appErr
return return
} }
@@ -1029,8 +1033,8 @@ func addGroupMembers(c *Context, w http.ResponseWriter, r *http.Request) {
} }
var newMembers *model.GroupModifyMembers var newMembers *model.GroupModifyMembers
if jsonErr := json.NewDecoder(r.Body).Decode(&newMembers); jsonErr != nil { if err := json.NewDecoder(r.Body).Decode(&newMembers); err != nil {
c.SetInvalidParamWithErr("addGroupMembers", jsonErr) c.SetInvalidParamWithErr("addGroupMembers", err)
return return
} }
@@ -1038,15 +1042,15 @@ func addGroupMembers(c *Context, w http.ResponseWriter, r *http.Request) {
defer c.LogAuditRec(auditRec) defer c.LogAuditRec(auditRec)
auditRec.AddEventParameter("addGroupMembers", newMembers) auditRec.AddEventParameter("addGroupMembers", newMembers)
members, err := c.App.UpsertGroupMembers(c.Params.GroupId, newMembers.UserIds) members, appErr := c.App.UpsertGroupMembers(c.Params.GroupId, newMembers.UserIds)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
b, marshalErr := json.Marshal(members) b, err := json.Marshal(members)
if marshalErr != nil { if err != nil {
c.Err = model.NewAppError("Api4.addGroupMembers", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("Api4.addGroupMembers", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
auditRec.Success() auditRec.Success()
@@ -1059,20 +1063,21 @@ func deleteGroupMembers(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
group, err := c.App.GetGroup(c.Params.GroupId, nil) group, appErr := c.App.GetGroup(c.Params.GroupId, nil)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
if group.Source != model.GroupSourceCustom { 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 return
} }
if lcErr := licensedAndConfiguredForGroupBySource(c.App, model.GroupSourceCustom); lcErr != nil { appErr = licensedAndConfiguredForGroupBySource(c.App, model.GroupSourceCustom)
lcErr.Where = "Api4.deleteGroup" if appErr != nil {
c.Err = lcErr appErr.Where = "Api4.deleteGroup"
c.Err = appErr
return return
} }
@@ -1082,8 +1087,8 @@ func deleteGroupMembers(c *Context, w http.ResponseWriter, r *http.Request) {
} }
var deleteBody *model.GroupModifyMembers var deleteBody *model.GroupModifyMembers
if jsonErr := json.NewDecoder(r.Body).Decode(&deleteBody); jsonErr != nil { if err := json.NewDecoder(r.Body).Decode(&deleteBody); err != nil {
c.SetInvalidParamWithErr("deleteGroupMembers", jsonErr) c.SetInvalidParamWithErr("deleteGroupMembers", err)
return return
} }
@@ -1091,15 +1096,15 @@ func deleteGroupMembers(c *Context, w http.ResponseWriter, r *http.Request) {
defer c.LogAuditRec(auditRec) defer c.LogAuditRec(auditRec)
auditRec.AddEventParameter("deleteGroupMembers", deleteBody) auditRec.AddEventParameter("deleteGroupMembers", deleteBody)
members, err := c.App.DeleteGroupMembers(c.Params.GroupId, deleteBody.UserIds) members, appErr := c.App.DeleteGroupMembers(c.Params.GroupId, deleteBody.UserIds)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
b, marshalErr := json.Marshal(members) b, err := json.Marshal(members)
if marshalErr != nil { if err != nil {
c.Err = model.NewAppError("Api4.addGroupMembers", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("Api4.addGroupMembers", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
auditRec.Success() auditRec.Success()
@@ -1109,27 +1114,27 @@ 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 // 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: // will have a blank 'Where' field, which should be subsequently set by the caller, for example:
// //
// err := licensedAndConfiguredForGroupBySource(c.App, group.Source) // err := licensedAndConfiguredForGroupBySource(c.App, group.Source)
// err.Where = "Api4.getGroup" // err.Where = "Api4.getGroup"
// //
// Temporarily, this function also checks for the CustomGroups feature flag. // Temporarily, this function also checks for the CustomGroups feature flag.
func licensedAndConfiguredForGroupBySource(app app.AppIface, source model.GroupSource) *model.AppError { func licensedAndConfiguredForGroupBySource(app app.AppIface, source model.GroupSource) *model.AppError {
lic := app.Srv().License() lic := app.Srv().License()
if lic == nil { 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 { 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 { 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) { 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 return nil

Просмотреть файл

@@ -98,7 +98,7 @@ func TestCreateGroup(t *testing.T) {
_, response, err := th.SystemAdminClient.CreateGroup(gbroken) _, response, err := th.SystemAdminClient.CreateGroup(gbroken)
require.Error(t, err) require.Error(t, err)
CheckNotImplementedStatus(t, response) CheckBadRequestStatus(t, response)
validGroup := &model.Group{ validGroup := &model.Group{
DisplayName: "dn_" + model.NewId(), DisplayName: "dn_" + model.NewId(),
@@ -137,7 +137,7 @@ func TestCreateGroup(t *testing.T) {
} }
_, response, err = th.SystemAdminClient.CreateGroup(unReferenceableCustomGroup) _, response, err = th.SystemAdminClient.CreateGroup(unReferenceableCustomGroup)
require.Error(t, err) require.Error(t, err)
CheckNotImplementedStatus(t, response) CheckBadRequestStatus(t, response)
unReferenceableCustomGroup.AllowReference = true unReferenceableCustomGroup.AllowReference = true
_, response, err = th.SystemAdminClient.CreateGroup(unReferenceableCustomGroup) _, response, err = th.SystemAdminClient.CreateGroup(unReferenceableCustomGroup)
require.NoError(t, err) require.NoError(t, err)
@@ -152,7 +152,7 @@ func TestCreateGroup(t *testing.T) {
} }
_, response, err = th.SystemAdminClient.CreateGroup(customGroupWithRemoteID) _, response, err = th.SystemAdminClient.CreateGroup(customGroupWithRemoteID)
require.Error(t, err) require.Error(t, err)
CheckNotImplementedStatus(t, response) CheckBadRequestStatus(t, response)
th.SystemAdminClient.Logout() th.SystemAdminClient.Logout()
_, response, err = th.SystemAdminClient.CreateGroup(g) _, response, err = th.SystemAdminClient.CreateGroup(g)
@@ -178,16 +178,16 @@ func TestDeleteGroup(t *testing.T) {
_, response, err := th.Client.DeleteGroup(g.Id) _, response, err := th.Client.DeleteGroup(g.Id)
require.Error(t, err) require.Error(t, err)
CheckNotImplementedStatus(t, response) CheckBadRequestStatus(t, response)
th.AddPermissionToRole(model.PermissionDeleteCustomGroup.Id, model.SystemUserRoleId) th.AddPermissionToRole(model.PermissionDeleteCustomGroup.Id, model.SystemUserRoleId)
_, response, err = th.Client.DeleteGroup(g.Id) _, response, err = th.Client.DeleteGroup(g.Id)
require.Error(t, err) require.Error(t, err)
CheckNotImplementedStatus(t, response) CheckBadRequestStatus(t, response)
_, response, err = th.Client.DeleteGroup(g.Id) _, response, err = th.Client.DeleteGroup(g.Id)
require.Error(t, err) require.Error(t, err)
CheckNotImplementedStatus(t, response) CheckBadRequestStatus(t, response)
_, response, err = th.Client.DeleteGroup("wertyuijhbgvfcde") _, response, err = th.Client.DeleteGroup("wertyuijhbgvfcde")
require.Error(t, err) require.Error(t, err)
@@ -939,7 +939,11 @@ func TestGetGroupsByChannel(t *testing.T) {
th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
_, _, response, err := client.GetGroupsByChannel(th.BasicChannel.Id, opts) _, _, response, err := client.GetGroupsByChannel(th.BasicChannel.Id, opts)
require.Error(t, err) 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")) 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) { th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
_, _, response, err := client.GetGroupsByTeam(th.BasicTeam.Id, opts) _, _, response, err := client.GetGroupsByTeam(th.BasicTeam.Id, opts)
require.Error(t, err) 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")) th.App.Srv().SetLicense(model.NewTestLicense("ldap"))
@@ -1248,7 +1256,7 @@ func TestGetGroups(t *testing.T) {
opts.Source = model.GroupSourceCustom opts.Source = model.GroupSourceCustom
_, response, err := th.Client.GetGroups(opts) _, response, err := th.Client.GetGroups(opts)
require.Error(t, err) require.Error(t, err)
CheckNotImplementedStatus(t, response) CheckBadRequestStatus(t, response)
// Specify ldap groups source when custom groups feature is disabled // Specify ldap groups source when custom groups feature is disabled
opts.Source = model.GroupSourceLdap opts.Source = model.GroupSourceLdap
@@ -1527,7 +1535,7 @@ func TestAddMembersToGroup(t *testing.T) {
_, response, upsertErr = th.SystemAdminClient.UpsertGroupMembers(ldapGroup.Id, members) _, response, upsertErr = th.SystemAdminClient.UpsertGroupMembers(ldapGroup.Id, members)
require.Error(t, upsertErr) require.Error(t, upsertErr)
CheckNotImplementedStatus(t, response) CheckBadRequestStatus(t, response)
} }
func TestDeleteMembersFromGroup(t *testing.T) { func TestDeleteMembersFromGroup(t *testing.T) {
@@ -1605,5 +1613,5 @@ func TestDeleteMembersFromGroup(t *testing.T) {
_, response, deleteErr = th.SystemAdminClient.DeleteGroupMembers(ldapGroup.Id, members) _, response, deleteErr = th.SystemAdminClient.DeleteGroupMembers(ldapGroup.Id, members)
require.Error(t, deleteErr) require.Error(t, deleteErr)
CheckNotImplementedStatus(t, response) CheckBadRequestStatus(t, response)
} }

Просмотреть файл

@@ -4,7 +4,7 @@
package api4 package api4
import ( import (
"io/ioutil" "io"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"net/url" "net/url"
@@ -89,7 +89,7 @@ func TestGetImage(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, http.StatusOK, resp.StatusCode) assert.Equal(t, http.StatusOK, resp.StatusCode)
respBody, err := ioutil.ReadAll(resp.Body) respBody, err := io.ReadAll(resp.Body)
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, "success", string(respBody)) assert.Equal(t, "success", string(respBody))

Просмотреть файл

@@ -28,7 +28,7 @@ func listImports(c *Context, w http.ResponseWriter, r *http.Request) {
data, err := json.Marshal(imports) data, err := json.Marshal(imports)
if err != nil { 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 return
} }

Просмотреть файл

@@ -36,9 +36,9 @@ func getTopReactionsForTeamSince(c *Context, w http.ResponseWriter, r *http.Requ
return return
} }
team, err := c.App.GetTeam(c.Params.TeamId) team, appErr := c.App.GetTeam(c.Params.TeamId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -47,27 +47,27 @@ func getTopReactionsForTeamSince(c *Context, w http.ResponseWriter, r *http.Requ
return return
} }
user, err := c.App.GetUser(c.AppContext.Session().UserId) user, appErr := c.App.GetUser(c.AppContext.Session().UserId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
startTime := model.StartOfDayForTimeRange(c.Params.TimeRange, user.GetTimezoneLocation()) 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(), StartUnixMilli: startTime.UnixMilli(),
Page: c.Params.Page, Page: c.Params.Page,
PerPage: c.Params.PerPage, PerPage: c.Params.PerPage,
}) })
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(topReactionList) js, err := json.Marshal(topReactionList)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getTopReactionsForTeamSince", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getTopReactionsForTeamSince", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
@@ -84,9 +84,9 @@ func getTopReactionsForUserSince(c *Context, w http.ResponseWriter, r *http.Requ
return return
} }
team, teamErr := c.App.GetTeam(c.Params.TeamId) team, appErr := c.App.GetTeam(c.Params.TeamId)
if teamErr != nil { if appErr != nil {
c.Err = teamErr c.Err = appErr
return return
} }
@@ -96,27 +96,27 @@ func getTopReactionsForUserSince(c *Context, w http.ResponseWriter, r *http.Requ
} }
} }
user, err := c.App.GetUser(c.AppContext.Session().UserId) user, appErr := c.App.GetUser(c.AppContext.Session().UserId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
startTime := model.StartOfDayForTimeRange(c.Params.TimeRange, user.GetTimezoneLocation()) 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(), StartUnixMilli: startTime.UnixMilli(),
Page: c.Params.Page, Page: c.Params.Page,
PerPage: c.Params.PerPage, PerPage: c.Params.PerPage,
}) })
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(topReactionList) js, err := json.Marshal(topReactionList)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getTopReactionsForUserSince", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getTopReactionsForUserSince", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
@@ -131,9 +131,9 @@ func getTopChannelsForTeamSince(c *Context, w http.ResponseWriter, r *http.Reque
return return
} }
team, err := c.App.GetTeam(c.Params.TeamId) team, appErr := c.App.GetTeam(c.Params.TeamId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -142,34 +142,34 @@ func getTopChannelsForTeamSince(c *Context, w http.ResponseWriter, r *http.Reque
return return
} }
user, err := c.App.GetUser(c.AppContext.Session().UserId) user, appErr := c.App.GetUser(c.AppContext.Session().UserId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
loc := user.GetTimezoneLocation() loc := user.GetTimezoneLocation()
startTime := model.StartOfDayForTimeRange(c.Params.TimeRange, loc) 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(), StartUnixMilli: startTime.UnixMilli(),
Page: c.Params.Page, Page: c.Params.Page,
PerPage: c.Params.PerPage, PerPage: c.Params.PerPage,
}) })
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
topChannels.PostCountByDuration, err = postCountByDurationViewModel(c, topChannels, startTime, c.Params.TimeRange, nil, loc) topChannels.PostCountByDuration, appErr = postCountByDurationViewModel(c, topChannels, startTime, c.Params.TimeRange, nil, loc)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(topChannels) js, err := json.Marshal(topChannels)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getTopChannelsForTeamSince", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getTopChannelsForTeamSince", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
@@ -186,9 +186,9 @@ func getTopChannelsForUserSince(c *Context, w http.ResponseWriter, r *http.Reque
return return
} }
team, teamErr := c.App.GetTeam(c.Params.TeamId) team, appErr := c.App.GetTeam(c.Params.TeamId)
if teamErr != nil { if appErr != nil {
c.Err = teamErr c.Err = appErr
return return
} }
@@ -198,35 +198,34 @@ func getTopChannelsForUserSince(c *Context, w http.ResponseWriter, r *http.Reque
} }
} }
user, err := c.App.GetUser(c.AppContext.Session().UserId) user, appErr := c.App.GetUser(c.AppContext.Session().UserId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
loc := user.GetTimezoneLocation() loc := user.GetTimezoneLocation()
startTime := model.StartOfDayForTimeRange(c.Params.TimeRange, loc) 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(), StartUnixMilli: startTime.UnixMilli(),
Page: c.Params.Page, Page: c.Params.Page,
PerPage: c.Params.PerPage, PerPage: c.Params.PerPage,
}) })
if appErr != nil {
if err != nil { c.Err = appErr
c.Err = err
return return
} }
topChannels.PostCountByDuration, err = postCountByDurationViewModel(c, topChannels, startTime, c.Params.TimeRange, &c.AppContext.Session().UserId, loc) topChannels.PostCountByDuration, appErr = postCountByDurationViewModel(c, topChannels, startTime, c.Params.TimeRange, &c.AppContext.Session().UserId, loc)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(topChannels) js, jsonErr := json.Marshal(topChannels)
if jsonErr != nil { if jsonErr != nil {
c.Err = model.NewAppError("getTopChannelsForUserSince", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getTopChannelsForUserSince", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
@@ -240,9 +239,9 @@ func getTopThreadsForTeamSince(c *Context, w http.ResponseWriter, r *http.Reques
return return
} }
team, err := c.App.GetTeam(c.Params.TeamId) team, appErr := c.App.GetTeam(c.Params.TeamId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -260,19 +259,19 @@ func getTopThreadsForTeamSince(c *Context, w http.ResponseWriter, r *http.Reques
startTime := model.StartOfDayForTimeRange(c.Params.TimeRange, user.GetTimezoneLocation()) 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(), StartUnixMilli: startTime.UnixMilli(),
Page: c.Params.Page, Page: c.Params.Page,
PerPage: c.Params.PerPage, PerPage: c.Params.PerPage,
}) })
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(topThreads) js, jsonError := json.Marshal(topThreads)
if jsonErr != nil { if jsonError != nil {
c.Err = model.NewAppError("getTopThreadsForTeamSince", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getTopThreadsForTeamSince", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
@@ -309,20 +308,19 @@ func getTopThreadsForUserSince(c *Context, w http.ResponseWriter, r *http.Reques
startTime := model.StartOfDayForTimeRange(c.Params.TimeRange, user.GetTimezoneLocation()) 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(), StartUnixMilli: startTime.UnixMilli(),
Page: c.Params.Page, Page: c.Params.Page,
PerPage: c.Params.PerPage, PerPage: c.Params.PerPage,
}) })
if appErr != nil {
if err != nil { c.Err = appErr
c.Err = err
return return
} }
js, jsonErr := json.Marshal(topThreads) js, err := json.Marshal(topThreads)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getTopThreadsForUserSince", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getTopThreadsForUserSince", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }

Просмотреть файл

@@ -33,14 +33,15 @@ func doPostAction(c *Context, w http.ResponseWriter, r *http.Request) {
var cookie *model.PostActionCookie var cookie *model.PostActionCookie
if actionRequest.Cookie != "" { if actionRequest.Cookie != "" {
cookie = &model.PostActionCookie{} 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 { 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 return
} }
err = json.Unmarshal([]byte(cookieStr), &cookie) err = json.Unmarshal([]byte(cookieStr), &cookie)
if err != nil { 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 return
} }
if !c.App.SessionHasPermissionToChannel(c.AppContext, *c.AppContext.Session(), cookie.ChannelId, model.PermissionReadChannel) { 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 return
} }
b, _ := json.Marshal(resp) err = json.NewEncoder(w).Encode(resp)
w.Write(b) if err != nil {
c.Logger.Warn("Error writing response", mlog.Err(err))
}
} }
func openDialog(c *Context, w http.ResponseWriter, r *http.Request) { 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 return
} }
if err := c.App.OpenInteractiveDialog(dialog); err != nil { if appErr := c.App.OpenInteractiveDialog(dialog); appErr != nil {
c.Err = err c.Err = appErr
return return
} }

Просмотреть файл

@@ -5,7 +5,7 @@ package api4
import ( import (
"encoding/json" "encoding/json"
"io/ioutil" "io"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"testing" "testing"
@@ -21,7 +21,7 @@ type testHandler struct {
} }
func (th *testHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 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.NoError(th.t, err)
assert.NotEmpty(th.t, string(bb)) assert.NotEmpty(th.t, string(bb))
var poir model.PostActionIntegrationRequest var poir model.PostActionIntegrationRequest

Просмотреть файл

@@ -162,15 +162,15 @@ func getJobs(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
jobs, err := c.App.GetJobsByTypesPage(validJobTypes, c.Params.Page, c.Params.PerPage) jobs, appErr := c.App.GetJobsByTypesPage(validJobTypes, c.Params.Page, c.Params.PerPage)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(jobs) js, err := json.Marshal(jobs)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getJobs", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getJobs", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(js) w.Write(js)
@@ -192,17 +192,18 @@ func getJobsByType(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
jobs, err := c.App.GetJobsByTypePage(c.Params.JobType, c.Params.Page, c.Params.PerPage) jobs, appErr := c.App.GetJobsByTypePage(c.Params.JobType, c.Params.Page, c.Params.PerPage)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(jobs) js, err := json.Marshal(jobs)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getJobsByType", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getJobsByType", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(js) w.Write(js)
} }

Просмотреть файл

@@ -111,9 +111,9 @@ func getLdapGroups(c *Context, w http.ResponseWriter, r *http.Request) {
opts.IsConfigured = c.Params.IsConfigured opts.IsConfigured = c.Params.IsConfigured
} }
groups, total, err := c.App.GetAllLdapGroupsPage(c.Params.Page, c.Params.PerPage, opts) groups, total, appErr := c.App.GetAllLdapGroupsPage(c.Params.Page, c.Params.PerPage, opts)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -130,12 +130,12 @@ func getLdapGroups(c *Context, w http.ResponseWriter, r *http.Request) {
mugs = append(mugs, mug) mugs = append(mugs, mug)
} }
b, marshalErr := json.Marshal(struct { b, err := json.Marshal(struct {
Count int `json:"count"` Count int `json:"count"`
Groups []*mixedUnlinkedGroup `json:"groups"` Groups []*mixedUnlinkedGroup `json:"groups"`
}{Count: total, Groups: mugs}) }{Count: total, Groups: mugs})
if marshalErr != nil { if err != nil {
c.Err = model.NewAppError("Api4.getLdapGroups", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("Api4.getLdapGroups", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
@@ -162,9 +162,9 @@ func linkLdapGroup(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
ldapGroup, err := c.App.GetLdapGroup(c.Params.RemoteId) ldapGroup, appErr := c.App.GetLdapGroup(c.Params.RemoteId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -175,9 +175,9 @@ func linkLdapGroup(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
group, err := c.App.GetGroupByRemoteID(ldapGroup.GetRemoteId(), model.GroupSourceLdap) group, appErr := c.App.GetGroupByRemoteID(ldapGroup.GetRemoteId(), model.GroupSourceLdap)
if err != nil && err.Id != "app.group.no_rows" { if appErr != nil && appErr.Id != "app.group.no_rows" {
c.Err = err c.Err = appErr
return return
} }
if group != nil { if group != nil {
@@ -203,9 +203,9 @@ func linkLdapGroup(c *Context, w http.ResponseWriter, r *http.Request) {
group.DeleteAt = 0 group.DeleteAt = 0
group.DisplayName = displayName group.DisplayName = displayName
group.RemoteId = ldapGroup.RemoteId group.RemoteId = ldapGroup.RemoteId
newOrUpdatedGroup, err = c.App.UpdateGroup(group) newOrUpdatedGroup, appErr = c.App.UpdateGroup(group)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
auditRec.AddEventResultState(newOrUpdatedGroup) auditRec.AddEventResultState(newOrUpdatedGroup)
@@ -222,9 +222,9 @@ func linkLdapGroup(c *Context, w http.ResponseWriter, r *http.Request) {
RemoteId: ldapGroup.RemoteId, RemoteId: ldapGroup.RemoteId,
Source: model.GroupSourceLdap, Source: model.GroupSourceLdap,
} }
newOrUpdatedGroup, err = c.App.CreateGroup(newGroup) newOrUpdatedGroup, appErr = c.App.CreateGroup(newGroup)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
auditRec.AddEventResultState(newOrUpdatedGroup) auditRec.AddEventResultState(newOrUpdatedGroup)
@@ -232,9 +232,9 @@ func linkLdapGroup(c *Context, w http.ResponseWriter, r *http.Request) {
status = http.StatusCreated status = http.StatusCreated
} }
b, marshalErr := json.Marshal(newOrUpdatedGroup) b, err := json.Marshal(newOrUpdatedGroup)
if marshalErr != nil { if err != nil {
c.Err = model.NewAppError("Api4.linkLdapGroup", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("Api4.linkLdapGroup", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }

Просмотреть файл

@@ -8,7 +8,6 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"net/http" "net/http"
"github.com/mattermost/mattermost-server/v6/shared/mlog" "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"` ReceiveEmailsAccepted bool `json:"receive_emails_accepted"`
} }
b, readErr := ioutil.ReadAll(r.Body) b, readErr := io.ReadAll(r.Body)
if readErr != nil { if readErr != nil {
c.Err = model.NewAppError("requestTrialLicense", "api.license.request-trial.bad-request", nil, "", http.StatusBadRequest) c.Err = model.NewAppError("requestTrialLicense", "api.license.request-trial.bad-request", nil, "", http.StatusBadRequest)
return return

Просмотреть файл

@@ -132,26 +132,27 @@ func getOAuthApps(c *Context, w http.ResponseWriter, r *http.Request) {
} }
var apps []*model.OAuthApp var apps []*model.OAuthApp
var err *model.AppError var appErr *model.AppError
if c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageSystemWideOAuth) { 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) { } 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 { } else {
c.SetPermissionError(model.PermissionManageOAuth) c.SetPermissionError(model.PermissionManageOAuth)
return return
} }
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(apps) js, err := json.Marshal(apps)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getOAuthApps", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getOAuthApps", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(js) w.Write(js)
} }
@@ -295,16 +296,17 @@ func getAuthorizedOAuthApps(c *Context, w http.ResponseWriter, r *http.Request)
return return
} }
apps, err := c.App.GetAuthorizedAppsForUser(c.Params.UserId, c.Params.Page, c.Params.PerPage) apps, appErr := c.App.GetAuthorizedAppsForUser(c.Params.UserId, c.Params.Page, c.Params.PerPage)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(apps) js, err := json.Marshal(apps)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getAuthorizedOAuthApps", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getAuthorizedOAuthApps", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(js) w.Write(js)
} }

Просмотреть файл

@@ -26,8 +26,9 @@ func appendAncillaryPermissions(c *Context, w http.ResponseWriter, r *http.Reque
permissions := strings.Split(keys[0], ",") permissions := strings.Split(keys[0], ",")
b, err := json.Marshal(model.AddAncillaryPermissions(permissions)) b, err := json.Marshal(model.AddAncillaryPermissions(permissions))
if err != nil { if err != nil {
c.SetJSONEncodingError() c.SetJSONEncodingError(err)
return return
} }
w.Write(b) w.Write(b)
} }

Просмотреть файл

@@ -251,9 +251,9 @@ func getWebappPlugins(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
manifests, err := c.App.GetActivePluginManifests() manifests, appErr := c.App.GetActivePluginManifests()
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -268,11 +268,12 @@ func getWebappPlugins(c *Context, w http.ResponseWriter, r *http.Request) {
} }
} }
js, jsonErr := json.Marshal(clientManifests) js, err := json.Marshal(clientManifests)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getWebappPlugins", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getWebappPlugins", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(js) w.Write(js)
} }
@@ -294,7 +295,7 @@ func getMarketplacePlugins(c *Context, w http.ResponseWriter, r *http.Request) {
filter, err := parseMarketplacePluginFilter(r.URL) filter, err := parseMarketplacePluginFilter(r.URL)
if err != nil { 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 return
} }
@@ -306,7 +307,7 @@ func getMarketplacePlugins(c *Context, w http.ResponseWriter, r *http.Request) {
json, err := json.Marshal(plugins) json, err := json.Marshal(plugins)
if err != nil { 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 return
} }

Просмотреть файл

@@ -8,7 +8,7 @@ import (
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil" "io"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"os" "os"
@@ -44,7 +44,7 @@ func TestPlugin(t *testing.T) {
}) })
path, _ := fileutils.FindDir("tests") 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) require.NoError(t, err)
// Install from URL // Install from URL
@@ -295,7 +295,7 @@ func TestNotifyClusterPluginEvent(t *testing.T) {
}) })
path, _ := fileutils.FindDir("tests") 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) require.NoError(t, err)
testCluster.ClearMessages() testCluster.ClearMessages()
@@ -378,7 +378,7 @@ func TestNotifyClusterPluginEvent(t *testing.T) {
func TestDisableOnRemove(t *testing.T) { func TestDisableOnRemove(t *testing.T) {
path, _ := fileutils.FindDir("tests") 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) require.NoError(t, err)
testCases := []struct { testCases := []struct {
@@ -723,7 +723,7 @@ func TestGetInstalledMarketplacePlugins(t *testing.T) {
} }
path, _ := fileutils.FindDir("tests") 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) require.NoError(t, err)
t.Run("marketplace client returns not-installed plugin", func(t *testing.T) { 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)) manifest, _, err := th.SystemAdminClient.UploadPlugin(bytes.NewReader(tarData))
require.NoError(t, err) 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.NoError(t, err)
require.True(t, svg.Is(testIcon)) require.True(t, svg.Is(testIcon))
testIconData := fmt.Sprintf("data:image/svg+xml;base64,%s", base64.StdEncoding.EncodeToString(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") 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) 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) 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.NoError(t, err)
require.True(t, svg.Is(testIcon)) require.True(t, svg.Is(testIcon))
testIconData := fmt.Sprintf("data:image/svg+xml;base64,%s", base64.StdEncoding.EncodeToString(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 // Upload one local plugin
path, _ := fileutils.FindDir("tests") 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) require.NoError(t, err)
manifest, _, err := th.SystemAdminClient.UploadPlugin(bytes.NewReader(tarData)) manifest, _, err := th.SystemAdminClient.UploadPlugin(bytes.NewReader(tarData))
@@ -1050,13 +1050,13 @@ func TestGetLocalPluginInMarketplace(t *testing.T) {
// Upload one local plugin // Upload one local plugin
path, _ := fileutils.FindDir("tests") 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) require.NoError(t, err)
manifest, _, err := th.SystemAdminClient.UploadPlugin(bytes.NewReader(tarData)) manifest, _, err := th.SystemAdminClient.UploadPlugin(bytes.NewReader(tarData))
require.NoError(t, err) 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.NoError(t, err)
require.True(t, svg.Is(testIcon)) require.True(t, svg.Is(testIcon))
testIconData := fmt.Sprintf("data:image/svg+xml;base64,%s", base64.StdEncoding.EncodeToString(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 // Upload one local plugin
path, _ := fileutils.FindDir("tests") 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) require.NoError(t, err)
manifest, _, err := th.SystemAdminClient.UploadPlugin(bytes.NewReader(tarData)) manifest, _, err := th.SystemAdminClient.UploadPlugin(bytes.NewReader(tarData))
require.NoError(t, err) 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.NoError(t, err)
require.True(t, svg.Is(testIcon)) require.True(t, svg.Is(testIcon))
testIconData := fmt.Sprintf("data:image/svg+xml;base64,%s", base64.StdEncoding.EncodeToString(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" signatureFilename := "testplugin2.tar.gz.sig"
signatureFileReader, err := os.Open(filepath.Join(path, signatureFilename)) signatureFileReader, err := os.Open(filepath.Join(path, signatureFilename))
require.NoError(t, err) require.NoError(t, err)
sigFile, err := ioutil.ReadAll(signatureFileReader) sigFile, err := io.ReadAll(signatureFileReader)
require.NoError(t, err) require.NoError(t, err)
pluginSignature := base64.StdEncoding.EncodeToString(sigFile) 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) require.NoError(t, err)
pluginServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { pluginServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
res.WriteHeader(http.StatusOK) res.WriteHeader(http.StatusOK)
@@ -1622,7 +1622,7 @@ func TestInstallMarketplacePlugin(t *testing.T) {
th2.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { th2.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
pluginSignatureFile, err := os.Open(filepath.Join(path, "testplugin.tar.gz.asc")) pluginSignatureFile, err := os.Open(filepath.Join(path, "testplugin.tar.gz.asc"))
require.NoError(t, err) require.NoError(t, err)
pluginSignatureData, err := ioutil.ReadAll(pluginSignatureFile) pluginSignatureData, err := io.ReadAll(pluginSignatureFile)
require.NoError(t, err) require.NoError(t, err)
key, err := os.Open(filepath.Join(path, "development-private-key.asc")) key, err := os.Open(filepath.Join(path, "development-private-key.asc"))

Просмотреть файл

@@ -970,9 +970,9 @@ func getFileInfosForPost(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
infos, err := c.App.GetFileInfosForPostWithMigration(c.Params.PostId, includeDeleted) infos, appErr := c.App.GetFileInfosForPostWithMigration(c.Params.PostId, includeDeleted)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -980,11 +980,12 @@ func getFileInfosForPost(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
js, jsonErr := json.Marshal(infos) js, err := json.Marshal(infos)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getFileInfosForPost", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getFileInfosForPost", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Header().Set("Cache-Control", "max-age=2592000, private") w.Header().Set("Cache-Control", "max-age=2592000, private")
w.Header().Set(model.HeaderEtagServer, model.GetEtagForFileInfos(infos)) w.Header().Set(model.HeaderEtagServer, model.GetEtagForFileInfos(infos))
w.Write(js) w.Write(js)

Просмотреть файл

@@ -62,17 +62,18 @@ func getReactions(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
reactions, err := c.App.GetReactionsForPost(c.Params.PostId) reactions, appErr := c.App.GetReactionsForPost(c.Params.PostId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(reactions) js, err := json.Marshal(reactions)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getReactions", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getReactions", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(js) w.Write(js)
} }
@@ -125,15 +126,15 @@ func getBulkReactions(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
} }
reactions, err := c.App.GetBulkReactionsForPosts(postIds) reactions, appErr := c.App.GetBulkReactionsForPosts(postIds)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(reactions) js, err := json.Marshal(reactions)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getBulkReactions", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getBulkReactions", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(js) w.Write(js)

Просмотреть файл

@@ -31,8 +31,8 @@ func remoteClusterPing(c *Context, w http.ResponseWriter, r *http.Request) {
} }
var frame model.RemoteClusterFrame var frame model.RemoteClusterFrame
if jsonErr := json.NewDecoder(r.Body).Decode(&frame); jsonErr != nil { if err := json.NewDecoder(r.Body).Decode(&frame); err != nil {
c.Err = model.NewAppError("remoteClusterPing", "api.unmarshal_error", nil, "", http.StatusBadRequest).Wrap(jsonErr) c.Err = model.NewAppError("remoteClusterPing", "api.unmarshal_error", nil, "", http.StatusBadRequest).Wrap(err)
return return
} }
@@ -47,15 +47,15 @@ func remoteClusterPing(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
rc, err := c.App.GetRemoteCluster(frame.RemoteId) rc, appErr := c.App.GetRemoteCluster(frame.RemoteId)
if err != nil { if appErr != nil {
c.SetInvalidRemoteIdError(frame.RemoteId) c.SetInvalidRemoteIdError(frame.RemoteId)
return return
} }
var ping model.RemoteClusterPing var ping model.RemoteClusterPing
if jsonErr := json.Unmarshal(frame.Msg.Payload, &ping); jsonErr != nil { if err := json.Unmarshal(frame.Msg.Payload, &ping); err != nil {
c.SetInvalidParam("msg.payload") c.SetInvalidParamWithErr("msg.payload", err)
return return
} }
ping.RecvAt = model.GetMillis() ping.RecvAt = model.GetMillis()
@@ -64,8 +64,10 @@ func remoteClusterPing(c *Context, w http.ResponseWriter, r *http.Request) {
metrics.IncrementRemoteClusterMsgReceivedCounter(rc.RemoteId) metrics.IncrementRemoteClusterMsgReceivedCounter(rc.RemoteId)
} }
resp, _ := json.Marshal(&ping) err := json.NewEncoder(w).Encode(ping)
w.Write(resp) if err != nil {
c.Logger.Warn("Error writing response", mlog.Err(err))
}
} }
func remoteClusterAcceptMessage(c *Context, w http.ResponseWriter, r *http.Request) { 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 var frame model.RemoteClusterFrame
if jsonErr := json.NewDecoder(r.Body).Decode(&frame); jsonErr != nil { if err := json.NewDecoder(r.Body).Decode(&frame); err != nil {
c.Err = model.NewAppError("remoteClusterAcceptMessage", "api.unmarshal_error", nil, "", http.StatusBadRequest).Wrap(jsonErr) c.Err = model.NewAppError("remoteClusterAcceptMessage", "api.unmarshal_error", nil, "", http.StatusBadRequest).Wrap(err)
return return
} }
if appErr := frame.IsValid(); appErr != nil { appErr = frame.IsValid()
if appErr != nil {
c.Err = appErr c.Err = appErr
return return
} }
@@ -97,8 +100,8 @@ func remoteClusterAcceptMessage(c *Context, w http.ResponseWriter, r *http.Reque
return return
} }
rc, err := c.App.GetRemoteCluster(frame.RemoteId) rc, appErr := c.App.GetRemoteCluster(frame.RemoteId)
if err != nil { if appErr != nil {
c.SetInvalidRemoteIdError(frame.RemoteId) c.SetInvalidRemoteIdError(frame.RemoteId)
return return
} }
@@ -107,11 +110,12 @@ func remoteClusterAcceptMessage(c *Context, w http.ResponseWriter, r *http.Reque
// pass message to Remote Cluster Service and write response // pass message to Remote Cluster Service and write response
resp := service.ReceiveIncomingMsg(rc, frame.Msg) resp := service.ReceiveIncomingMsg(rc, frame.Msg)
b, errMarshall := json.Marshal(resp) b, err := json.Marshal(resp)
if errMarshall != nil { if err != nil {
c.Err = model.NewAppError("remoteClusterAcceptMessage", "api.marshal_error", nil, errMarshall.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("remoteClusterAcceptMessage", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(b) w.Write(b)
} }

Просмотреть файл

@@ -32,15 +32,15 @@ func getAllRoles(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
roles, err := c.App.GetAllRoles() roles, appErr := c.App.GetAllRoles()
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(roles) js, err := json.Marshal(roles)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getAllRoles", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getAllRoles", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
@@ -95,17 +95,18 @@ func getRolesByNames(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
roles, err := c.App.GetRolesByNames(cleanedRoleNames) roles, appErr := c.App.GetRolesByNames(cleanedRoleNames)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(roles) js, err := json.Marshal(roles)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getRolesByNames", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getRolesByNames", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(js) w.Write(js)
} }
@@ -116,8 +117,8 @@ func patchRole(c *Context, w http.ResponseWriter, r *http.Request) {
} }
var patch model.RolePatch var patch model.RolePatch
if jsonErr := json.NewDecoder(r.Body).Decode(&patch); jsonErr != nil { if err := json.NewDecoder(r.Body).Decode(&patch); err != nil {
c.SetInvalidParamWithErr("role", jsonErr) c.SetInvalidParamWithErr("role", err)
return return
} }
@@ -125,9 +126,9 @@ func patchRole(c *Context, w http.ResponseWriter, r *http.Request) {
auditRec.AddEventParameter("role_patch", patch) auditRec.AddEventParameter("role_patch", patch)
defer c.LogAuditRec(auditRec) defer c.LogAuditRec(auditRec)
oldRole, err := c.App.GetRole(c.Params.RoleId) oldRole, appErr := c.App.GetRole(c.Params.RoleId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
auditRec.AddEventPriorState(oldRole) auditRec.AddEventPriorState(oldRole)
@@ -203,9 +204,9 @@ func patchRole(c *Context, w http.ResponseWriter, r *http.Request) {
} }
} }
role, err := c.App.PatchRole(oldRole, &patch) role, appErr := c.App.PatchRole(oldRole, &patch)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }

Просмотреть файл

@@ -5,7 +5,7 @@ package api4
import ( import (
"encoding/json" "encoding/json"
"io/ioutil" "io"
"mime" "mime"
"mime/multipart" "mime/multipart"
"net/http" "net/http"
@@ -139,7 +139,7 @@ func addSamlIdpCertificate(c *Context, w http.ResponseWriter, r *http.Request) {
auditRec.AddMeta("type", d) auditRec.AddMeta("type", d)
if d == "application/x-pem-file" { if d == "application/x-pem-file" {
body, err := ioutil.ReadAll(r.Body) body, err := io.ReadAll(r.Body)
if err != nil { if err != nil {
c.Err = model.NewAppError("addSamlIdpCertificate", "api.admin.saml.set_certificate_from_metadata.invalid_body.app_error", nil, err.Error(), http.StatusBadRequest) c.Err = model.NewAppError("addSamlIdpCertificate", "api.admin.saml.set_certificate_from_metadata.invalid_body.app_error", nil, err.Error(), http.StatusBadRequest)
return return

Просмотреть файл

@@ -93,17 +93,18 @@ func getSchemes(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
schemes, err := c.App.GetSchemesPage(c.Params.Scope, c.Params.Page, c.Params.PerPage) schemes, appErr := c.App.GetSchemesPage(c.Params.Scope, c.Params.Page, c.Params.PerPage)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(schemes) js, err := json.Marshal(schemes)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getSchemes", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getSchemes", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(js) w.Write(js)
} }
@@ -118,9 +119,9 @@ func getTeamsForScheme(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
scheme, err := c.App.GetScheme(c.Params.SchemeId) scheme, appErr := c.App.GetScheme(c.Params.SchemeId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -129,17 +130,18 @@ func getTeamsForScheme(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
teams, err := c.App.GetTeamsForSchemePage(scheme, c.Params.Page, c.Params.PerPage) teams, appErr := c.App.GetTeamsForSchemePage(scheme, c.Params.Page, c.Params.PerPage)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(teams) js, err := json.Marshal(teams)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getTeamsForScheme", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getTeamsForScheme", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(js) w.Write(js)
} }

Просмотреть файл

@@ -50,9 +50,10 @@ func getSharedChannels(c *Context, w http.ResponseWriter, r *http.Request) {
b, err := json.Marshal(channels) b, err := json.Marshal(channels)
if err != nil { if err != nil {
c.SetJSONEncodingError() c.SetJSONEncodingError(err)
return return
} }
w.Write(b) w.Write(b)
} }
@@ -80,7 +81,7 @@ func getRemoteClusterInfo(c *Context, w http.ResponseWriter, r *http.Request) {
b, err := json.Marshal(remoteInfo) b, err := json.Marshal(remoteInfo)
if err != nil { if err != nil {
c.SetJSONEncodingError() c.SetJSONEncodingError(err)
return return
} }
w.Write(b) w.Write(b)

Просмотреть файл

@@ -64,17 +64,18 @@ func getUserStatusesByIds(c *Context, w http.ResponseWriter, r *http.Request) {
} }
// No permission check required // No permission check required
statuses, err := c.App.GetUserStatusesByIds(userIds) statuses, appErr := c.App.GetUserStatusesByIds(userIds)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(statuses) js, err := json.Marshal(statuses)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getUserStatusesByIds", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getUserStatusesByIds", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(js) w.Write(js)
} }

Просмотреть файл

@@ -195,7 +195,11 @@ func getSystemPing(c *Context, w http.ResponseWriter, r *http.Request) {
} }
func testEmail(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 { if cfg == nil {
cfg = c.App.Config() cfg = c.App.Config()
} }
@@ -215,9 +219,9 @@ func testEmail(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
err := c.App.TestEmail(c.AppContext.Session().UserId, cfg) appErr := c.App.TestEmail(c.AppContext.Session().UserId, cfg)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -242,9 +246,9 @@ func testSiteURL(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
err := c.App.TestSiteURL(siteURL) appErr := c.App.TestSiteURL(siteURL)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -260,9 +264,9 @@ func getAudits(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
audits, err := c.App.GetAuditsPage("", c.Params.Page, c.Params.PerPage) audits, appErr := c.App.GetAuditsPage("", c.Params.Page, c.Params.PerPage)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -309,9 +313,9 @@ func invalidateCaches(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
err := c.App.Srv().InvalidateAllCaches() appErr := c.App.Srv().InvalidateAllCaches()
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -335,9 +339,9 @@ func getLogs(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
lines, err := c.App.GetLogs(c.Params.Page, c.Params.LogsPerPage) lines, appErr := c.App.GetLogs(c.Params.Page, c.Params.LogsPerPage)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return 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"] lvl := m["level"]
msg := m["message"] msg := m["message"]
@@ -382,7 +394,10 @@ func postLog(c *Context, w http.ResponseWriter, r *http.Request) {
} }
m["message"] = msg 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) { 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 return
} }
rows, err := c.App.GetAnalytics(name, teamId) rows, appErr := c.App.GetAnalytics(name, teamId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -420,15 +435,15 @@ func getLatestVersion(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
resp, err := c.App.GetLatestVersion("https://api.github.com/repos/mattermost/mattermost-server/releases/latest") resp, appErr := c.App.GetLatestVersion("https://api.github.com/repos/mattermost/mattermost-server/releases/latest")
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
b, jsonErr := json.Marshal(resp) b, err := json.Marshal(resp)
if jsonErr != nil { if err != nil {
c.Logger.Warn("Unable to marshal JSON for latest version.", mlog.Err(jsonErr)) c.Logger.Warn("Unable to marshal JSON for latest version.", mlog.Err(err))
w.WriteHeader(http.StatusInternalServerError) 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) { 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 { if cfg == nil {
cfg = c.App.Config() cfg = c.App.Config()
} }
@@ -471,9 +490,9 @@ func testS3(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
err := c.App.CheckMandatoryS3Fields(&cfg.FileSettings) appErr := c.App.CheckMandatoryS3Fields(&cfg.FileSettings)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -481,7 +500,7 @@ func testS3(c *Context, w http.ResponseWriter, r *http.Request) {
cfg.FileSettings.AmazonS3SecretAccessKey = c.App.Config().FileSettings.AmazonS3SecretAccessKey cfg.FileSettings.AmazonS3SecretAccessKey = c.App.Config().FileSettings.AmazonS3SecretAccessKey
} }
appErr := c.App.TestFileStoreConnectionWithConfig(&cfg.FileSettings) appErr = c.App.TestFileStoreConnectionWithConfig(&cfg.FileSettings)
if appErr != nil { if appErr != nil {
c.Err = appErr c.Err = appErr
return return
@@ -776,17 +795,18 @@ func getWarnMetricsStatus(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
status, err := c.App.GetWarnMetricsStatus() status, appErr := c.App.GetWarnMetricsStatus()
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(status) js, err := json.Marshal(status)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getWarnMetricsStatus", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getWarnMetricsStatus", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(js) w.Write(js)
} }
@@ -871,10 +891,9 @@ func getProductNotices(c *Context, w http.ResponseWriter, r *http.Request) {
clientVersion := r.URL.Query().Get("clientVersion") clientVersion := r.URL.Query().Get("clientVersion")
locale := r.URL.Query().Get("locale") locale := r.URL.Query().Get("locale")
notices, err := c.App.GetProductNotices(c.AppContext, c.AppContext.Session().UserId, c.Params.TeamId, client, clientVersion, locale) notices, appErr := c.App.GetProductNotices(c.AppContext, c.AppContext.Session().UserId, c.Params.TeamId, client, clientVersion, locale)
if appErr != nil {
if err != nil { c.Err = appErr
c.Err = err
return return
} }
result, _ := notices.Marshal() result, _ := notices.Marshal()
@@ -887,9 +906,9 @@ func updateViewedProductNotices(c *Context, w http.ResponseWriter, r *http.Reque
c.LogAudit("attempt") c.LogAudit("attempt")
ids := model.ArrayFromJSON(r.Body) ids := model.ArrayFromJSON(r.Body)
err := c.App.UpdateViewedProductNotices(c.AppContext.Session().UserId, ids) appErr := c.App.UpdateViewedProductNotices(c.AppContext.Session().UserId, ids)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -910,7 +929,7 @@ func getOnboarding(c *Context, w http.ResponseWriter, r *http.Request) {
firstAdminCompleteSetupObj, err := c.App.GetOnboarding() firstAdminCompleteSetupObj, err := c.App.GetOnboarding()
if err != nil { 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 return
} }
@@ -931,7 +950,7 @@ func completeOnboarding(c *Context, w http.ResponseWriter, r *http.Request) {
onboardingRequest, err := model.CompleteOnboardingRequestFromReader(r.Body) onboardingRequest, err := model.CompleteOnboardingRequestFromReader(r.Body)
if err != nil { 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 return
} }
auditRec.AddEventParameter("install_plugin", onboardingRequest.InstallPlugins) auditRec.AddEventParameter("install_plugin", onboardingRequest.InstallPlugins)
@@ -962,9 +981,9 @@ func getAppliedSchemaMigrations(c *Context, w http.ResponseWriter, r *http.Reque
return return
} }
js, jsonErr := json.Marshal(migrations) js, err := json.Marshal(migrations)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getAppliedMigrations", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getAppliedMigrations", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }

Просмотреть файл

@@ -33,7 +33,7 @@ func localCheckIntegrity(c *Context, w http.ResponseWriter, r *http.Request) {
data, err := json.Marshal(results) data, err := json.Marshal(results)
if err != nil { 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 return
} }

Просмотреть файл

@@ -8,7 +8,7 @@ import (
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil" "io"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"os" "os"
@@ -64,7 +64,7 @@ func TestGetPing(t *testing.T) {
resp, err := client.DoAPIGet("/system/ping", "") resp, err := client.DoAPIGet("/system/ping", "")
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode) require.Equal(t, http.StatusOK, resp.StatusCode)
respBytes, err := ioutil.ReadAll(resp.Body) respBytes, err := io.ReadAll(resp.Body)
require.NoError(t, err) require.NoError(t, err)
respString := string(respBytes) respString := string(respBytes)
require.NotContains(t, respString, "TestFeatureFlag") require.NotContains(t, respString, "TestFeatureFlag")
@@ -77,7 +77,7 @@ func TestGetPing(t *testing.T) {
resp, err = client.DoAPIGet("/system/ping", "") resp, err = client.DoAPIGet("/system/ping", "")
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode) require.Equal(t, http.StatusOK, resp.StatusCode)
respBytes, err = ioutil.ReadAll(resp.Body) respBytes, err = io.ReadAll(resp.Body)
require.NoError(t, err) require.NoError(t, err)
respString = string(respBytes) respString = string(respBytes)
require.Contains(t, respString, "testvalue") require.Contains(t, respString, "testvalue")
@@ -130,7 +130,7 @@ func TestEmailTest(t *testing.T) {
defer th.TearDown() defer th.TearDown()
client := th.Client client := th.Client
dir, err := ioutil.TempDir("", "") dir, err := os.MkdirTemp("", "")
require.NoError(t, err) require.NoError(t, err)
defer os.RemoveAll(dir) defer os.RemoveAll(dir)
@@ -817,7 +817,7 @@ func TestPushNotificationAck(t *testing.T) {
resp := httptest.NewRecorder() resp := httptest.NewRecorder()
req := httptest.NewRequest("POST", "/api/v4/notifications/ack", nil) req := httptest.NewRequest("POST", "/api/v4/notifications/ack", nil)
req.Header.Set(model.HeaderAuth, "Bearer "+session.Token) 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) handler.ServeHTTP(resp, req)
assert.Equal(t, http.StatusForbidden, resp.Code) assert.Equal(t, http.StatusForbidden, resp.Code)
@@ -833,11 +833,11 @@ func TestCompleteOnboarding(t *testing.T) {
signatureFilename := "testplugin2.tar.gz.sig" signatureFilename := "testplugin2.tar.gz.sig"
signatureFileReader, err := os.Open(filepath.Join(path, signatureFilename)) signatureFileReader, err := os.Open(filepath.Join(path, signatureFilename))
require.NoError(t, err) require.NoError(t, err)
sigFile, err := ioutil.ReadAll(signatureFileReader) sigFile, err := io.ReadAll(signatureFileReader)
require.NoError(t, err) require.NoError(t, err)
pluginSignature := base64.StdEncoding.EncodeToString(sigFile) 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) require.NoError(t, err)
pluginServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { pluginServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
res.WriteHeader(http.StatusOK) res.WriteHeader(http.StatusOK)

Просмотреть файл

@@ -485,19 +485,20 @@ func getTeamsForUser(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
teams, err := c.App.GetTeamsForUser(c.Params.UserId) teams, appErr := c.App.GetTeamsForUser(c.Params.UserId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
c.App.SanitizeTeams(*c.AppContext.Session(), teams) c.App.SanitizeTeams(*c.AppContext.Session(), teams)
js, jsonErr := json.Marshal(teams) js, err := json.Marshal(teams)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getTeamsForUser", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getTeamsForUser", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(js) w.Write(js)
} }
@@ -516,15 +517,15 @@ func getTeamsUnreadForUser(c *Context, w http.ResponseWriter, r *http.Request) {
teamId := r.URL.Query().Get("exclude_team") teamId := r.URL.Query().Get("exclude_team")
includeCollapsedThreads := r.URL.Query().Get("include_collapsed_threads") == "true" includeCollapsedThreads := r.URL.Query().Get("include_collapsed_threads") == "true"
unreadTeamsList, err := c.App.GetTeamsUnreadForUser(teamId, c.Params.UserId, includeCollapsedThreads) unreadTeamsList, appErr := c.App.GetTeamsUnreadForUser(teamId, c.Params.UserId, includeCollapsedThreads)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(unreadTeamsList) js, err := json.Marshal(unreadTeamsList)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getTeamsUnreadForUser", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getTeamsUnreadForUser", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(js) w.Write(js)
@@ -541,9 +542,9 @@ func getTeamMember(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
canSee, err := c.App.UserCanSeeOtherUser(c.AppContext.Session().UserId, c.Params.UserId) canSee, appErr := c.App.UserCanSeeOtherUser(c.AppContext.Session().UserId, c.Params.UserId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -552,9 +553,9 @@ func getTeamMember(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
team, err := c.App.GetTeamMember(c.Params.TeamId, c.Params.UserId) team, appErr := c.App.GetTeamMember(c.Params.TeamId, c.Params.UserId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -578,9 +579,9 @@ func getTeamMembers(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
restrictions, err := c.App.GetViewUsersRestrictions(c.AppContext.Session().UserId) restrictions, appErr := c.App.GetViewUsersRestrictions(c.AppContext.Session().UserId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -590,17 +591,18 @@ func getTeamMembers(c *Context, w http.ResponseWriter, r *http.Request) {
ViewRestrictions: restrictions, ViewRestrictions: restrictions,
} }
members, err := c.App.GetTeamMembers(c.Params.TeamId, c.Params.Page*c.Params.PerPage, c.Params.PerPage, teamMembersGetOptions) members, appErr := c.App.GetTeamMembers(c.Params.TeamId, c.Params.Page*c.Params.PerPage, c.Params.PerPage, teamMembersGetOptions)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(members) js, err := json.Marshal(members)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getTeamMembers", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getTeamMembers", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(js) w.Write(js)
} }
@@ -615,9 +617,9 @@ func getTeamMembersForUser(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
canSee, err := c.App.UserCanSeeOtherUser(c.AppContext.Session().UserId, c.Params.UserId) canSee, appErr := c.App.UserCanSeeOtherUser(c.AppContext.Session().UserId, c.Params.UserId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -626,17 +628,18 @@ func getTeamMembersForUser(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
members, err := c.App.GetTeamMembersForUser(c.Params.UserId, "", true) members, appErr := c.App.GetTeamMembersForUser(c.Params.UserId, "", true)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(members) js, err := json.Marshal(members)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getTeamMembersForUser", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getTeamMembersForUser", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(js) w.Write(js)
} }
@@ -646,10 +649,10 @@ func getTeamMembersByIds(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
userIds := model.ArrayFromJSON(r.Body) var userIDs []string
err := json.NewDecoder(r.Body).Decode(&userIDs)
if len(userIds) == 0 { if err != nil || len(userIDs) == 0 {
c.SetInvalidParam("user_ids") c.SetInvalidParamWithErr("user_ids", err)
return return
} }
@@ -658,23 +661,24 @@ func getTeamMembersByIds(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
restrictions, err := c.App.GetViewUsersRestrictions(c.AppContext.Session().UserId) restrictions, appErr := c.App.GetViewUsersRestrictions(c.AppContext.Session().UserId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
members, err := c.App.GetTeamMembersByIds(c.Params.TeamId, userIds, restrictions) members, appErr := c.App.GetTeamMembersByIds(c.Params.TeamId, userIDs, restrictions)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(members) js, err := json.Marshal(members)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getTeamMembersByIds", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getTeamMembersByIds", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(js) w.Write(js)
} }
@@ -815,7 +819,7 @@ func addTeamMembers(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
var err *model.AppError var appErr *model.AppError
var members []*model.TeamMember var members []*model.TeamMember
if jsonErr := json.NewDecoder(r.Body).Decode(&members); jsonErr != nil { if jsonErr := json.NewDecoder(r.Body).Decode(&members); jsonErr != nil {
c.SetInvalidParamWithErr("members", jsonErr) c.SetInvalidParamWithErr("members", jsonErr)
@@ -843,9 +847,9 @@ func addTeamMembers(c *Context, w http.ResponseWriter, r *http.Request) {
} }
auditRec.AddMeta("user_ids", memberIDs) auditRec.AddMeta("user_ids", memberIDs)
team, err := c.App.GetTeam(c.Params.TeamId) team, appErr := c.App.GetTeam(c.Params.TeamId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
auditRec.AddMeta("team", team) 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 { if v, ok := err.(*model.AppError); ok {
c.Err = v c.Err = v
} else { } 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 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 { for _, member := range members {
if member.TeamId != c.Params.TeamId { if member.TeamId != c.Params.TeamId {
c.SetInvalidParam("team_id for member with user_id=" + member.UserId) 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 return
} }
userIds = append(userIds, member.UserId) userIDs = append(userIDs, member.UserId)
} }
if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), c.Params.TeamId, model.PermissionAddUserToTeam) { 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 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)) errList := make([]string, 0, len(membersWithErrors))
for _, m := range membersWithErrors { for _, m := range membersWithErrors {
if m.Error != nil { if m.Error != nil {
@@ -897,21 +901,23 @@ func addTeamMembers(c *Context, w http.ResponseWriter, r *http.Request) {
} }
auditRec.AddMeta("errors", errList) auditRec.AddMeta("errors", errList)
} }
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
var js []byte var (
var jsonErr error js []byte
err error
)
if graceful { if graceful {
// in 'graceful' mode we allow a different return value, notifying the client which users were not added // 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 { } else {
js, jsonErr = json.Marshal(model.TeamMembersWithErrorToTeamMembers(membersWithErrors)) js, err = json.Marshal(model.TeamMembersWithErrorToTeamMembers(membersWithErrors))
} }
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("addTeamMembers", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("addTeamMembers", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return 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) { func getAllTeams(c *Context, w http.ResponseWriter, r *http.Request) {
teams := []*model.Team{} teams := []*model.Team{}
var err *model.AppError var appErr *model.AppError
var teamsWithCount *model.TeamsWithCount var teamsWithCount *model.TeamsWithCount
opts := &model.TeamSearch{} opts := &model.TeamSearch{}
@@ -1126,26 +1132,28 @@ func getAllTeams(c *Context, w http.ResponseWriter, r *http.Request) {
} }
if c.Params.IncludeTotalCount { if c.Params.IncludeTotalCount {
teamsWithCount, err = c.App.GetAllTeamsPageWithCount(offset, limit, opts) teamsWithCount, appErr = c.App.GetAllTeamsPageWithCount(offset, limit, opts)
} else { } else {
teams, err = c.App.GetAllTeamsPage(offset, limit, opts) teams, appErr = c.App.GetAllTeamsPage(offset, limit, opts)
} }
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
var js []byte var (
var jsonErr error js []byte
err error
)
if c.Params.IncludeTotalCount { if c.Params.IncludeTotalCount {
c.App.SanitizeTeams(*c.AppContext.Session(), teamsWithCount.Teams) c.App.SanitizeTeams(*c.AppContext.Session(), teamsWithCount.Teams)
js, jsonErr = json.Marshal(teamsWithCount) js, err = json.Marshal(teamsWithCount)
} else { } else {
c.App.SanitizeTeams(*c.AppContext.Session(), teams) c.App.SanitizeTeams(*c.AppContext.Session(), teams)
js, jsonErr = json.Marshal(teams) js, err = json.Marshal(teams)
} }
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getAllTeams", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getAllTeams", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return 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) { func searchTeams(c *Context, w http.ResponseWriter, r *http.Request) {
var props model.TeamSearch var props model.TeamSearch
if jsonErr := json.NewDecoder(r.Body).Decode(&props); jsonErr != nil { if err := json.NewDecoder(r.Body).Decode(&props); err != nil {
c.SetInvalidParamWithErr("team_search", jsonErr) c.SetInvalidParamWithErr("team_search", err)
return return
} }
// Only system managers may use the ExcludePolicyConstrained field // 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) props.IncludePolicyID = model.NewBool(true)
} }
var teams []*model.Team var (
var totalCount int64 teams []*model.Team
var err *model.AppError totalCount int64
appErr *model.AppError
)
if c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionListPrivateTeams) && c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionListPublicTeams) { 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) { } else if c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionListPrivateTeams) {
if props.Page != nil || props.PerPage != nil { 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) c.Err = model.NewAppError("searchTeams", "api.team.search_teams.pagination_not_implemented.private_team_search", nil, "", http.StatusNotImplemented)
return return
} }
teams, err = c.App.SearchPrivateTeams(&props) teams, appErr = c.App.SearchPrivateTeams(&props)
} else if c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionListPublicTeams) { } else if c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionListPublicTeams) {
if props.Page != nil || props.PerPage != nil { 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) c.Err = model.NewAppError("searchTeams", "api.team.search_teams.pagination_not_implemented.public_team_search", nil, "", http.StatusNotImplemented)
return return
} }
teams, err = c.App.SearchPublicTeams(&props) teams, appErr = c.App.SearchPublicTeams(&props)
} else { } else {
teams = []*model.Team{} teams = []*model.Team{}
} }
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -1203,9 +1213,9 @@ func searchTeams(c *Context, w http.ResponseWriter, r *http.Request) {
twc := map[string]any{"teams": teams, "total_count": totalCount} twc := map[string]any{"teams": teams, "total_count": totalCount}
payload = model.ToJSON(twc) payload = model.ToJSON(twc)
} else { } else {
js, jsonErr := json.Marshal(teams) js, err := json.Marshal(teams)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("searchTeams", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("searchTeams", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
payload = js payload = js
@@ -1357,26 +1367,26 @@ func inviteUsersToTeam(c *Context, w http.ResponseWriter, r *http.Request) {
bf, err := io.ReadAll(r.Body) bf, err := io.ReadAll(r.Body)
if err != nil { 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 return
} }
memberInvite := &model.MemberInvite{} memberInvite := &model.MemberInvite{}
if jsonErr := json.Unmarshal(bf, memberInvite); jsonErr != nil { 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, jsonErr.Error(), http.StatusBadRequest) 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 return
} }
emailList := memberInvite.Emails emailList := memberInvite.Emails
for i := range emailList {
emailList[i] = strings.ToLower(emailList[i])
}
if len(emailList) == 0 { if len(emailList) == 0 {
c.SetInvalidParam("user_email") c.SetInvalidParam("user_email")
return return
} }
for i := range emailList {
emailList[i] = strings.ToLower(emailList[i])
}
auditRec := c.MakeAuditRecord("inviteUsersToTeam", audit.Fail) auditRec := c.MakeAuditRecord("inviteUsersToTeam", audit.Fail)
defer c.LogAuditRec(auditRec) defer c.LogAuditRec(auditRec)
auditRec.AddEventParameter("member_invite", memberInvite) auditRec.AddEventParameter("member_invite", memberInvite)
@@ -1391,9 +1401,9 @@ func inviteUsersToTeam(c *Context, w http.ResponseWriter, r *http.Request) {
if graceful { if graceful {
var invitesWithError []*model.EmailInviteWithError var invitesWithError []*model.EmailInviteWithError
var err *model.AppError var appErr *model.AppError
if emailList != nil { 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 { if invitesWithError != nil {
@@ -1405,8 +1415,8 @@ func inviteUsersToTeam(c *Context, w http.ResponseWriter, r *http.Request) {
} }
auditRec.AddMeta("errors", errList) auditRec.AddMeta("errors", errList)
} }
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return 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 // we then manually schedule the job to send another invite after 48 hours
_, e := c.App.Srv().Jobs.CreateJob(model.JobTypeResendInvitationEmail, jobData) _, appErr = c.App.Srv().Jobs.CreateJob(model.JobTypeResendInvitationEmail, jobData)
if e != nil { if appErr != nil {
c.Err = model.NewAppError("Api4.inviteUsersToTeam", e.Id, nil, e.Error(), e.StatusCode) c.Err = model.NewAppError("Api4.inviteUsersToTeam", appErr.Id, nil, appErr.Error(), appErr.StatusCode)
return return
} }
// in graceful mode we return both the successful ones and the failed ones // in graceful mode we return both the successful ones and the failed ones
js, jsonErr := json.Marshal(invitesWithError) js, err := json.Marshal(invitesWithError)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("inviteUsersToTeam", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("inviteUsersToTeam", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(js) w.Write(js)
} else { } else {
err := c.App.InviteNewUsersToTeam(emailList, c.Params.TeamId, c.AppContext.Session().UserId) appErr := c.App.InviteNewUsersToTeam(emailList, c.Params.TeamId, c.AppContext.Session().UserId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
ReturnStatusOK(w) ReturnStatusOK(w)
@@ -1475,8 +1486,8 @@ func inviteGuestsToChannels(c *Context, w http.ResponseWriter, r *http.Request)
} }
var guestsInvite model.GuestsInvite var guestsInvite model.GuestsInvite
if jsonErr := json.NewDecoder(r.Body).Decode(&guestsInvite); jsonErr != nil { 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(jsonErr) c.Err = model.NewAppError("Api4.inviteGuestsToChannels", "api.team.invite_guests_to_channels.invalid_body.app_error", nil, "", http.StatusBadRequest).Wrap(err)
return return
} }
auditRec.AddEventParameter("guests_invite", guestsInvite) 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 { for i, email := range guestsInvite.Emails {
guestsInvite.Emails[i] = strings.ToLower(email) guestsInvite.Emails[i] = strings.ToLower(email)
} }
if err := guestsInvite.IsValid(); err != nil { if appErr := guestsInvite.IsValid(); appErr != nil {
c.Err = err c.Err = appErr
return return
} }
auditRec.AddMeta("email_count", len(guestsInvite.Emails)) auditRec.AddMeta("email_count", len(guestsInvite.Emails))
@@ -1495,32 +1506,33 @@ func inviteGuestsToChannels(c *Context, w http.ResponseWriter, r *http.Request)
if graceful { if graceful {
var invitesWithError []*model.EmailInviteWithError var invitesWithError []*model.EmailInviteWithError
var err *model.AppError var appErr *model.AppError
if guestsInvite.Emails != nil { 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)) errList := make([]string, 0, len(invitesWithError))
for _, inv := range invitesWithError { for _, inv := range invitesWithError {
errList = append(errList, model.EmailInviteWithErrorToString(inv)) errList = append(errList, model.EmailInviteWithErrorToString(inv))
} }
auditRec.AddMeta("errors", errList) auditRec.AddMeta("errors", errList)
c.Err = err c.Err = appErr
return return
} }
// in graceful mode we return both the successful ones and the failed ones // in graceful mode we return both the successful ones and the failed ones
js, jsonErr := json.Marshal(invitesWithError) js, err := json.Marshal(invitesWithError)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("inviteGuestsToChannel", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("inviteGuestsToChannel", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(js) w.Write(js)
} else { } else {
err := c.App.InviteGuestsToChannels(c.Params.TeamId, &guestsInvite, c.AppContext.Session().UserId) appErr := c.App.InviteGuestsToChannels(c.Params.TeamId, &guestsInvite, c.AppContext.Session().UserId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
ReturnStatusOK(w) ReturnStatusOK(w)
@@ -1534,9 +1546,9 @@ func getInviteInfo(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
team, err := c.App.GetTeamByInviteId(c.Params.InviteId) team, appErr := c.App.GetTeamByInviteId(c.Params.InviteId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -1545,12 +1557,22 @@ func getInviteInfo(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
result := map[string]string{} result := struct {
result["display_name"] = team.DisplayName DisplayName string `json:"display_name"`
result["description"] = team.Description Description string `json:"description"`
result["name"] = team.Name Name string `json:"name"`
result["id"] = team.Id ID string `json:"id"`
w.Write([]byte(model.MapToJSON(result))) }{
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) { 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 return
} }
users, totalCount, err := c.App.TeamMembersMinusGroupMembers( users, totalCount, appErr := c.App.TeamMembersMinusGroupMembers(
c.Params.TeamId, c.Params.TeamId,
groupIDs, groupIDs,
c.Params.Page, c.Params.Page,
c.Params.PerPage, c.Params.PerPage,
) )
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
b, marshalErr := json.Marshal(&model.UsersWithGroupsAndCount{ b, err := json.Marshal(&model.UsersWithGroupsAndCount{
Users: users, Users: users,
Count: totalCount, Count: totalCount,
}) })
if marshalErr != nil { if err != nil {
c.Err = model.NewAppError("Api4.teamMembersMinusGroupMembers", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("Api4.teamMembersMinusGroupMembers", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }

Просмотреть файл

@@ -81,12 +81,13 @@ func localInviteUsersToTeam(c *Context, w http.ResponseWriter, r *http.Request)
bf, err := io.ReadAll(r.Body) bf, err := io.ReadAll(r.Body)
if err != nil { 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 return
} }
memberInvite := &model.MemberInvite{} memberInvite := &model.MemberInvite{}
if jsonErr := json.Unmarshal(bf, memberInvite); jsonErr != nil { err = json.Unmarshal(bf, memberInvite)
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 != 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 return
} }
@@ -117,14 +118,14 @@ func localInviteUsersToTeam(c *Context, w http.ResponseWriter, r *http.Request)
auditRec.AddMeta("channels", memberInvite.ChannelIds) auditRec.AddMeta("channels", memberInvite.ChannelIds)
} }
team, nErr := c.App.Srv().Store.Team().Get(c.Params.TeamId) team, err := c.App.Srv().Store.Team().Get(c.Params.TeamId)
if nErr != nil { if err != nil {
var nfErr *store.ErrNotFound var nfErr *store.ErrNotFound
switch { switch {
case errors.As(nErr, &nfErr): case errors.As(err, &nfErr):
c.Err = model.NewAppError("localInviteUsersToTeam", "app.team.get.find.app_error", nil, nfErr.Error(), http.StatusNotFound) c.Err = model.NewAppError("localInviteUsersToTeam", "app.team.get.find.app_error", nil, "", http.StatusNotFound).Wrap(err)
default: 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 return
} }
@@ -135,7 +136,7 @@ func localInviteUsersToTeam(c *Context, w http.ResponseWriter, r *http.Request)
if len(memberInvite.ChannelIds) > 0 { if len(memberInvite.ChannelIds) > 0 {
channels, err = c.App.Srv().Store.Channel().GetChannelsByIds(memberInvite.ChannelIds, false) channels, err = c.App.Srv().Store.Channel().GetChannelsByIds(memberInvite.ChannelIds, false)
if err != nil { 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) auditRec.AddMeta("errors", errList)
if len(goodEmails) > 0 { if len(goodEmails) > 0 {
var eErr error
var invitesWithErrors2 []*model.EmailInviteWithError var invitesWithErrors2 []*model.EmailInviteWithError
if len(channels) > 0 { 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...) invitesWithErrors = append(invitesWithErrors, invitesWithErrors2...)
} else { } 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 { switch {
case errors.Is(err, email.NoRateLimiterError): 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): 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: 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 return
} }
} }
// in graceful mode we return both the successful ones and the failed ones // in graceful mode we return both the successful ones and the failed ones
js, jsonErr := json.Marshal(invitesWithErrors) js, err := json.Marshal(invitesWithErrors)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("localInviteUsersToTeam", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("localInviteUsersToTeam", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(js) w.Write(js)
} else { } else {
var invalidEmailList []string var invalidEmailList []string
@@ -202,11 +204,11 @@ func localInviteUsersToTeam(c *Context, w http.ResponseWriter, r *http.Request)
if err != nil { if err != nil {
switch { switch {
case errors.Is(err, email.NoRateLimiterError): 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): 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: 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 return
} }

Просмотреть файл

@@ -25,13 +25,13 @@ func (api *API) InitUsage() {
func getPostsUsage(c *Context, w http.ResponseWriter, r *http.Request) { func getPostsUsage(c *Context, w http.ResponseWriter, r *http.Request) {
count, appErr := c.App.GetPostsUsage() count, appErr := c.App.GetPostsUsage()
if appErr != nil { 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 return
} }
json, err := json.Marshal(&model.PostsUsage{Count: count}) json, err := json.Marshal(&model.PostsUsage{Count: count})
if err != nil { 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 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) { func getStorageUsage(c *Context, w http.ResponseWriter, r *http.Request) {
usage, appErr := c.App.GetStorageUsage() usage, appErr := c.App.GetStorageUsage()
if appErr != nil { 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 return
} }
usage = utils.RoundOffToZeroesResolution(float64(usage), 8) usage = utils.RoundOffToZeroesResolution(float64(usage), 8)
json, err := json.Marshal(&model.StorageUsage{Bytes: usage}) json, err := json.Marshal(&model.StorageUsage{Bytes: usage})
if err != nil { 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 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) { func getTeamsUsage(c *Context, w http.ResponseWriter, r *http.Request) {
teamsUsage, appErr := c.App.GetTeamsUsage() teamsUsage, appErr := c.App.GetTeamsUsage()
if appErr != nil { 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 return
} }
if teamsUsage == nil { 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) json, err := json.Marshal(teamsUsage)
if err != nil { 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 return
} }
@@ -79,7 +79,7 @@ func getIntegrationsUsage(c *Context, w http.ResponseWriter, r *http.Request) {
if !*c.App.Config().PluginSettings.Enable { if !*c.App.Config().PluginSettings.Enable {
json, err := json.Marshal(&model.IntegrationsUsage{}) json, err := json.Marshal(&model.IntegrationsUsage{})
if err != nil { 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 return
} }
@@ -95,7 +95,7 @@ func getIntegrationsUsage(c *Context, w http.ResponseWriter, r *http.Request) {
json, err := json.Marshal(usage) json, err := json.Marshal(usage)
if err != nil { 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 return
} }

Просмотреть файл

@@ -622,32 +622,37 @@ func getUsersByGroupChannelIds(c *Context, w http.ResponseWriter, r *http.Reques
return return
} }
usersByChannelId, err := c.App.GetUsersByGroupChannelIds(c.AppContext, channelIds, c.IsSystemAdmin()) usersByChannelId, appErr := c.App.GetUsersByGroupChannelIds(c.AppContext, channelIds, c.IsSystemAdmin())
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
b, _ := json.Marshal(usersByChannelId) err := json.NewEncoder(w).Encode(usersByChannelId)
w.Write(b) if err != nil {
c.Logger.Warn("Error writing response", mlog.Err(err))
}
} }
func getUsers(c *Context, w http.ResponseWriter, r *http.Request) { func getUsers(c *Context, w http.ResponseWriter, r *http.Request) {
inTeamId := r.URL.Query().Get("in_team") var (
notInTeamId := r.URL.Query().Get("not_in_team") query = r.URL.Query()
inChannelId := r.URL.Query().Get("in_channel") inTeamId = query.Get("in_team")
inGroupId := r.URL.Query().Get("in_group") notInTeamId = query.Get("not_in_team")
notInGroupId := r.URL.Query().Get("not_in_group") inChannelId = query.Get("in_channel")
notInChannelId := r.URL.Query().Get("not_in_channel") inGroupId = query.Get("in_group")
groupConstrained := r.URL.Query().Get("group_constrained") notInGroupId = query.Get("not_in_group")
withoutTeam := r.URL.Query().Get("without_team") notInChannelId = query.Get("not_in_channel")
inactive := r.URL.Query().Get("inactive") groupConstrained = query.Get("group_constrained")
active := r.URL.Query().Get("active") withoutTeam = query.Get("without_team")
role := r.URL.Query().Get("role") inactive = query.Get("inactive")
sort := r.URL.Query().Get("sort") active = query.Get("active")
rolesString := r.URL.Query().Get("roles") role = query.Get("role")
channelRolesString := r.URL.Query().Get("channel_roles") sort = query.Get("sort")
teamRolesString := r.URL.Query().Get("team_roles") rolesString = query.Get("roles")
channelRolesString = query.Get("channel_roles")
teamRolesString = query.Get("team_roles")
)
if notInChannelId != "" && inTeamId == "" { if notInChannelId != "" && inTeamId == "" {
c.SetInvalidURLParam("team_id") c.SetInvalidURLParam("team_id")
@@ -674,10 +679,12 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
withoutTeamBool, _ := strconv.ParseBool(withoutTeam) var (
groupConstrainedBool, _ := strconv.ParseBool(groupConstrained) withoutTeamBool, _ = strconv.ParseBool(withoutTeam)
inactiveBool, _ := strconv.ParseBool(inactive) groupConstrainedBool, _ = strconv.ParseBool(groupConstrained)
activeBool, _ := strconv.ParseBool(active) inactiveBool, _ = strconv.ParseBool(inactive)
activeBool, _ = strconv.ParseBool(active)
)
if inactiveBool && activeBool { if inactiveBool && activeBool {
c.SetInvalidURLParam("inactive") 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) restrictions, appErr := c.App.GetViewUsersRestrictions(c.AppContext.Session().UserId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -736,14 +743,16 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) {
ViewRestrictions: restrictions, ViewRestrictions: restrictions,
} }
var profiles []*model.User var (
etag := "" profiles []*model.User
etag string
)
if inChannelId != "" { if inChannelId != "" {
if !*c.App.Config().TeamSettings.ExperimentalViewArchivedChannels { if !*c.App.Config().TeamSettings.ExperimentalViewArchivedChannels {
channel, appErr := c.App.GetChannel(c.AppContext, inChannelId) channel, cErr := c.App.GetChannel(c.AppContext, inChannelId)
if appErr != nil { if cErr != nil {
c.Err = appErr c.Err = cErr
return return
} }
if channel.DeleteAt != 0 { if channel.DeleteAt != 0 {
@@ -760,14 +769,14 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
profiles, err = c.App.GetUsersWithoutTeamPage(userGetOptions, c.IsSystemAdmin()) profiles, appErr = c.App.GetUsersWithoutTeamPage(userGetOptions, c.IsSystemAdmin())
} else if notInChannelId != "" { } else if notInChannelId != "" {
if !c.App.SessionHasPermissionToChannel(c.AppContext, *c.AppContext.Session(), notInChannelId, model.PermissionReadChannel) { if !c.App.SessionHasPermissionToChannel(c.AppContext, *c.AppContext.Session(), notInChannelId, model.PermissionReadChannel) {
c.SetPermissionError(model.PermissionReadChannel) c.SetPermissionError(model.PermissionReadChannel)
return 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 != "" { } else if notInTeamId != "" {
if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), notInTeamId, model.PermissionViewTeam) { if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), notInTeamId, model.PermissionViewTeam) {
c.SetPermissionError(model.PermissionViewTeam) c.SetPermissionError(model.PermissionViewTeam)
@@ -779,7 +788,7 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) {
return 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 != "" { } else if inTeamId != "" {
if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), inTeamId, model.PermissionViewTeam) { if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), inTeamId, model.PermissionViewTeam) {
c.SetPermissionError(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" { 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" { } 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 { } else {
etag = c.App.GetUsersInTeamEtag(inTeamId, restrictions.Hash()) etag = c.App.GetUsersInTeamEtag(inTeamId, restrictions.Hash())
if c.HandleEtag(etag, "Get Users in Team", w, r) { if c.HandleEtag(etag, "Get Users in Team", w, r) {
return return
} }
profiles, err = c.App.GetUsersInTeamPage(userGetOptions, c.IsSystemAdmin()) profiles, appErr = c.App.GetUsersInTeamPage(userGetOptions, c.IsSystemAdmin())
} }
} else if inChannelId != "" { } else if inChannelId != "" {
if !c.App.SessionHasPermissionToChannel(c.AppContext, *c.AppContext.Session(), inChannelId, model.PermissionReadChannel) { 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" { if sort == "status" {
profiles, err = c.App.GetUsersInChannelPageByStatus(userGetOptions, c.IsSystemAdmin()) profiles, appErr = c.App.GetUsersInChannelPageByStatus(userGetOptions, c.IsSystemAdmin())
} else if sort == "admin" { } else if sort == "admin" {
profiles, err = c.App.GetUsersInChannelPageByAdmin(userGetOptions, c.IsSystemAdmin()) profiles, appErr = c.App.GetUsersInChannelPageByAdmin(userGetOptions, c.IsSystemAdmin())
} else { } else {
profiles, err = c.App.GetUsersInChannelPage(userGetOptions, c.IsSystemAdmin()) profiles, appErr = c.App.GetUsersInChannelPage(userGetOptions, c.IsSystemAdmin())
} }
} else if inGroupId != "" { } else if inGroupId != "" {
if gErr := requireGroupAccess(c, inGroupId); gErr != nil { if gErr := requireGroupAccess(c, inGroupId); gErr != nil {
@@ -817,34 +826,35 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
profiles, _, err = c.App.GetGroupMemberUsersPage(inGroupId, c.Params.Page, c.Params.PerPage) profiles, _, appErr = c.App.GetGroupMemberUsersPage(inGroupId, c.Params.Page, c.Params.PerPage)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
} else if notInGroupId != "" { } else if notInGroupId != "" {
if gErr := requireGroupAccess(c, notInGroupId); gErr != nil { appErr = requireGroupAccess(c, notInGroupId)
gErr.Where = "Api.getUsers" if appErr != nil {
c.Err = gErr appErr.Where = "Api.getUsers"
c.Err = appErr
return return
} }
profiles, err = c.App.GetUsersNotInGroupPage(notInGroupId, c.Params.Page, c.Params.PerPage) profiles, appErr = c.App.GetUsersNotInGroupPage(notInGroupId, c.Params.Page, c.Params.PerPage)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
} else { } else {
userGetOptions, err = c.App.RestrictUsersGetByPermissions(c.AppContext.Session().UserId, userGetOptions) userGetOptions, appErr = c.App.RestrictUsersGetByPermissions(c.AppContext.Session().UserId, userGetOptions)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
profiles, err = c.App.GetUsersPage(userGetOptions, c.IsSystemAdmin()) profiles, appErr = c.App.GetUsersPage(userGetOptions, c.IsSystemAdmin())
} }
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -853,9 +863,9 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) {
} }
c.App.UpdateLastActivityAtIfNeeded(*c.AppContext.Session()) c.App.UpdateLastActivityAtIfNeeded(*c.AppContext.Session())
js, jsonErr := json.Marshal(profiles) js, err := json.Marshal(profiles)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getUsers", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getUsers", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
@@ -882,10 +892,10 @@ func requireGroupAccess(c *web.Context, groupID string) *model.AppError {
} }
func getUsersByIds(c *Context, w http.ResponseWriter, r *http.Request) { func getUsersByIds(c *Context, w http.ResponseWriter, r *http.Request) {
userIds := model.ArrayFromJSON(r.Body) var userIDs []string
err := json.NewDecoder(r.Body).Decode(&userIDs)
if len(userIds) == 0 { if err != nil || len(userIDs) == 0 {
c.SetInvalidParam("user_ids") c.SetInvalidParamWithErr("user_ids", err)
return return
} }
@@ -896,30 +906,30 @@ func getUsersByIds(c *Context, w http.ResponseWriter, r *http.Request) {
} }
if sinceString != "" { if sinceString != "" {
since, parseError := strconv.ParseInt(sinceString, 10, 64) since, sErr := strconv.ParseInt(sinceString, 10, 64)
if parseError != nil { if sErr != nil {
c.SetInvalidParam("since") c.SetInvalidParamWithErr("since", sErr)
return return
} }
options.Since = since options.Since = since
} }
restrictions, err := c.App.GetViewUsersRestrictions(c.AppContext.Session().UserId) restrictions, appErr := c.App.GetViewUsersRestrictions(c.AppContext.Session().UserId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
options.ViewRestrictions = restrictions options.ViewRestrictions = restrictions
users, err := c.App.GetUsersByIds(userIds, options) users, appErr := c.App.GetUsersByIds(userIDs, options)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(users) js, err := json.Marshal(users)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getUsersByIds", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getUsersByIds", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return 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) { func getUsersByNames(c *Context, w http.ResponseWriter, r *http.Request) {
usernames := model.ArrayFromJSON(r.Body) var usernames []string
err := json.NewDecoder(r.Body).Decode(&usernames)
if len(usernames) == 0 { if err != nil || len(usernames) == 0 {
c.SetInvalidParam("usernames") c.SetInvalidParamWithErr("usernames", err)
return 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 { if err != nil {
c.Err = err c.Err = model.NewAppError("getUsersByNames", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(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)
return 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) { func getKnownUsers(c *Context, w http.ResponseWriter, r *http.Request) {
userIds, err := c.App.GetKnownUsers(c.AppContext.Session().UserId) userIDs, appErr := c.App.GetKnownUsers(c.AppContext.Session().UserId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
data, _ := json.Marshal(userIds) err := json.NewEncoder(w).Encode(userIDs)
if err != nil {
w.Write(data) c.Logger.Warn("Error writing response", mlog.Err(err))
}
} }
func searchUsers(c *Context, w http.ResponseWriter, r *http.Request) { func searchUsers(c *Context, w http.ResponseWriter, r *http.Request) {
var props model.UserSearch var props model.UserSearch
if jsonErr := json.NewDecoder(r.Body).Decode(&props); jsonErr != nil { if err := json.NewDecoder(r.Body).Decode(&props); err != nil {
c.SetInvalidParamWithErr("props", jsonErr) c.SetInvalidParamWithErr("props", err)
return return
} }
@@ -989,17 +1000,17 @@ func searchUsers(c *Context, w http.ResponseWriter, r *http.Request) {
} }
if props.InGroupId != "" { if props.InGroupId != "" {
if gErr := requireGroupAccess(c, props.InGroupId); gErr != nil { if appErr := requireGroupAccess(c, props.InGroupId); appErr != nil {
gErr.Where = "Api.searchUsers" appErr.Where = "Api.searchUsers"
c.Err = gErr c.Err = appErr
return return
} }
} }
if props.NotInGroupId != "" { if props.NotInGroupId != "" {
if gErr := requireGroupAccess(c, props.NotInGroupId); gErr != nil { if appErr := requireGroupAccess(c, props.NotInGroupId); appErr != nil {
gErr.Where = "Api.searchUsers" appErr.Where = "Api.searchUsers"
c.Err = gErr c.Err = appErr
return return
} }
} }
@@ -1048,21 +1059,21 @@ func searchUsers(c *Context, w http.ResponseWriter, r *http.Request) {
options.AllowFullNames = *c.App.Config().PrivacySettings.ShowFullName options.AllowFullNames = *c.App.Config().PrivacySettings.ShowFullName
} }
options, err := c.App.RestrictUsersSearchByPermissions(c.AppContext.Session().UserId, options) options, appErr := c.App.RestrictUsersSearchByPermissions(c.AppContext.Session().UserId, options)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
profiles, err := c.App.SearchUsers(&props, options) profiles, appErr := c.App.SearchUsers(&props, options)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(profiles) js, err := json.Marshal(profiles)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("searchUsers", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("searchUsers", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
@@ -1973,9 +1984,9 @@ func getSessions(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
sessions, err := c.App.GetSessions(c.Params.UserId) sessions, appErr := c.App.GetSessions(c.Params.UserId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -1983,11 +1994,12 @@ func getSessions(c *Context, w http.ResponseWriter, r *http.Request) {
session.Sanitize() session.Sanitize()
} }
js, jsonErr := json.Marshal(sessions) js, err := json.Marshal(sessions)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getSessions", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getSessions", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(js) w.Write(js)
} }
@@ -2343,8 +2355,8 @@ func searchUserAccessTokens(c *Context, w http.ResponseWriter, r *http.Request)
} }
var props model.UserAccessTokenSearch var props model.UserAccessTokenSearch
if jsonErr := json.NewDecoder(r.Body).Decode(&props); jsonErr != nil { if err := json.NewDecoder(r.Body).Decode(&props); err != nil {
c.SetInvalidParamWithErr("user_access_token_search", jsonErr) c.SetInvalidParamWithErr("user_access_token_search", err)
return return
} }
@@ -2353,15 +2365,15 @@ func searchUserAccessTokens(c *Context, w http.ResponseWriter, r *http.Request)
return return
} }
accessTokens, err := c.App.SearchUserAccessTokens(props.Term) accessTokens, appErr := c.App.SearchUserAccessTokens(props.Term)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(accessTokens) js, err := json.Marshal(accessTokens)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("searchUserAccessTokens", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("searchUserAccessTokens", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
@@ -2374,15 +2386,15 @@ func getUserAccessTokens(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
accessTokens, err := c.App.GetUserAccessTokens(c.Params.Page, c.Params.PerPage) accessTokens, appErr := c.App.GetUserAccessTokens(c.Params.Page, c.Params.PerPage)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(accessTokens) js, err := json.Marshal(accessTokens)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("searchUserAccessTokens", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("searchUserAccessTokens", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
@@ -2405,15 +2417,15 @@ func getUserAccessTokensForUser(c *Context, w http.ResponseWriter, r *http.Reque
return return
} }
accessTokens, err := c.App.GetUserAccessTokensForUser(c.Params.UserId, c.Params.Page, c.Params.PerPage) accessTokens, appErr := c.App.GetUserAccessTokensForUser(c.Params.UserId, c.Params.Page, c.Params.PerPage)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(accessTokens) js, err := json.Marshal(accessTokens)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("searchUserAccessTokens", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("searchUserAccessTokens", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
@@ -2431,9 +2443,9 @@ func getUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
accessToken, err := c.App.GetUserAccessToken(c.Params.TokenId, true) accessToken, appErr := c.App.GetUserAccessToken(c.Params.TokenId, true)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -2791,9 +2803,9 @@ func convertUserToBot(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
user, err := c.App.GetUser(c.Params.UserId) user, appErr := c.App.GetUser(c.Params.UserId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -2807,9 +2819,9 @@ func convertUserToBot(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
bot, err := c.App.ConvertUserToBot(user) bot, appErr := c.App.ConvertUserToBot(user)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -2817,9 +2829,9 @@ func convertUserToBot(c *Context, w http.ResponseWriter, r *http.Request) {
auditRec.AddEventResultState(bot) auditRec.AddEventResultState(bot)
auditRec.AddEventObjectType("bot") auditRec.AddEventObjectType("bot")
js, jsonErr := json.Marshal(bot) js, err := json.Marshal(bot)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("convertUserToBot", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("convertUserToBot", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
@@ -2839,15 +2851,15 @@ func getUploadsForUser(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
uss, err := c.App.GetUploadSessionsForUser(c.Params.UserId) uss, appErr := c.App.GetUploadSessionsForUser(c.Params.UserId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(uss) js, err := json.Marshal(uss)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("getUploadsForUser", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("getUploadsForUser", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(js) w.Write(js)
@@ -3252,14 +3264,16 @@ func getUsersWithInvalidEmails(c *Context, w http.ResponseWriter, r *http.Reques
return return
} }
users, err := c.App.GetUsersWithInvalidEmails(c.Params.Page, c.Params.PerPage) users, appErr := c.App.GetUsersWithInvalidEmails(c.Params.Page, c.Params.PerPage)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
b, _ := json.Marshal(users) err := json.NewEncoder(w).Encode(users)
w.Write(b) if err != nil {
c.Logger.Warn("Error writing response", mlog.Err(err))
}
} }
func getRecentSearches(c *Context, w http.ResponseWriter, r *http.Request) { func getRecentSearches(c *Context, w http.ResponseWriter, r *http.Request) {

Просмотреть файл

@@ -100,45 +100,47 @@ func localGetUsers(c *Context, w http.ResponseWriter, r *http.Request) {
ViewRestrictions: nil, ViewRestrictions: nil,
} }
var err *model.AppError var (
var profiles []*model.User appErr *model.AppError
etag := "" profiles []*model.User
etag string
)
if withoutTeamBool, _ := strconv.ParseBool(withoutTeam); withoutTeamBool { 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 != "" { } 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 != "" { } else if notInTeamId != "" {
etag = c.App.GetUsersNotInTeamEtag(inTeamId, "") etag = c.App.GetUsersNotInTeamEtag(inTeamId, "")
if c.HandleEtag(etag, "Get Users Not in Team", w, r) { if c.HandleEtag(etag, "Get Users Not in Team", w, r) {
return 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 != "" { } else if inTeamId != "" {
if sort == "last_activity_at" { 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" { } 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 { } else {
etag = c.App.GetUsersInTeamEtag(inTeamId, "") etag = c.App.GetUsersInTeamEtag(inTeamId, "")
if c.HandleEtag(etag, "Get Users in Team", w, r) { if c.HandleEtag(etag, "Get Users in Team", w, r) {
return return
} }
profiles, err = c.App.GetUsersInTeamPage(userGetOptions, c.IsSystemAdmin()) profiles, appErr = c.App.GetUsersInTeamPage(userGetOptions, c.IsSystemAdmin())
} }
} else if inChannelId != "" { } else if inChannelId != "" {
if sort == "status" { if sort == "status" {
profiles, err = c.App.GetUsersInChannelPageByStatus(userGetOptions, c.IsSystemAdmin()) profiles, appErr = c.App.GetUsersInChannelPageByStatus(userGetOptions, c.IsSystemAdmin())
} else { } else {
profiles, err = c.App.GetUsersInChannelPage(userGetOptions, c.IsSystemAdmin()) profiles, appErr = c.App.GetUsersInChannelPage(userGetOptions, c.IsSystemAdmin())
} }
} else { } else {
profiles, err = c.App.GetUsersPage(userGetOptions, c.IsSystemAdmin()) profiles, appErr = c.App.GetUsersPage(userGetOptions, c.IsSystemAdmin())
} }
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
@@ -146,9 +148,9 @@ func localGetUsers(c *Context, w http.ResponseWriter, r *http.Request) {
w.Header().Set(model.HeaderEtagServer, etag) w.Header().Set(model.HeaderEtagServer, etag)
} }
js, jsonErr := json.Marshal(profiles) js, err := json.Marshal(profiles)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("localGetUsers", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("localGetUsers", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
@@ -170,23 +172,23 @@ func localGetUsersByIds(c *Context, w http.ResponseWriter, r *http.Request) {
} }
if sinceString != "" { if sinceString != "" {
since, parseError := strconv.ParseInt(sinceString, 10, 64) since, err := strconv.ParseInt(sinceString, 10, 64)
if parseError != nil { if err != nil {
c.SetInvalidParam("since") c.SetInvalidParamWithErr("since", err)
return return
} }
options.Since = since options.Since = since
} }
users, err := c.App.GetUsersByIds(userIds, options) users, appErr := c.App.GetUsersByIds(userIds, options)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(users) js, err := json.Marshal(users)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("localGetUsersByIds", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("localGetUsersByIds", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return 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) { func localGetUploadsForUser(c *Context, w http.ResponseWriter, r *http.Request) {
uss, err := c.App.GetUploadSessionsForUser(c.Params.UserId) uss, appErr := c.App.GetUploadSessionsForUser(c.Params.UserId)
if err != nil { if appErr != nil {
c.Err = err c.Err = appErr
return return
} }
js, jsonErr := json.Marshal(uss) js, err := json.Marshal(uss)
if jsonErr != nil { if err != nil {
c.Err = model.NewAppError("localGetUploadsForUser", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) c.Err = model.NewAppError("localGetUploadsForUser", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return return
} }
w.Write(js) w.Write(js)
} }

Просмотреть файл

@@ -1188,7 +1188,7 @@ func TestSearchUsers(t *testing.T) {
t.Run("Requires ldap license when searching in group", func(t *testing.T) { t.Run("Requires ldap license when searching in group", func(t *testing.T) {
_, resp, err = th.SystemAdminClient.SearchUsers(search) _, resp, err = th.SystemAdminClient.SearchUsers(search)
require.Error(t, err) require.Error(t, err)
CheckNotImplementedStatus(t, resp) CheckForbiddenStatus(t, resp)
}) })
th.App.Srv().SetLicense(model.NewTestLicense("ldap")) 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) { t.Run("Requires ldap license", func(t *testing.T) {
_, response, err := th.SystemAdminClient.GetUsersInGroup(group.Id, 0, 60, "") _, response, err := th.SystemAdminClient.GetUsersInGroup(group.Id, 0, 60, "")
require.Error(t, err) require.Error(t, err)
CheckNotImplementedStatus(t, response) CheckForbiddenStatus(t, response)
}) })
th.App.Srv().SetLicense(model.NewTestLicense("ldap")) th.App.Srv().SetLicense(model.NewTestLicense("ldap"))

Просмотреть файл

@@ -178,24 +178,26 @@ func updateIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) {
} }
func getIncomingHooks(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") var (
userId := c.AppContext.Session().UserId teamID = r.URL.Query().Get("team_id")
userID = c.AppContext.Session().UserId
var hooks []*model.IncomingWebhook hooks []*model.IncomingWebhook
var err *model.AppError appErr *model.AppError
)
if teamId != "" { if teamID != "" {
if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), teamId, model.PermissionManageIncomingWebhooks) { if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), teamID, model.PermissionManageIncomingWebhooks) {
c.SetPermissionError(model.PermissionManageIncomingWebhooks) c.SetPermissionError(model.PermissionManageIncomingWebhooks)
return return
} }
// Remove userId as a filter if they have permission to manage others. // Remove userId as a filter if they have permission to manage others.
if c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), teamId, model.PermissionManageOthersIncomingWebhooks) { if c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), teamID, model.PermissionManageOthersIncomingWebhooks) {
userId = "" 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 { } else {
if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageIncomingWebhooks) { if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageIncomingWebhooks) {
c.SetPermissionError(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. // Remove userId as a filter if they have permission to manage others.
if c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageOthersIncomingWebhooks) { 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 { if err != nil {
c.Err = err c.Err = model.NewAppError("getIncomingHooks", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return 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) 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) { func getOutgoingHooks(c *Context, w http.ResponseWriter, r *http.Request) {
channelId := r.URL.Query().Get("channel_id") var (
teamId := r.URL.Query().Get("team_id") query = r.URL.Query()
userId := c.AppContext.Session().UserId channelID = query.Get("channel_id")
teamID = query.Get("team_id")
userID = c.AppContext.Session().UserId
var hooks []*model.OutgoingWebhook hooks []*model.OutgoingWebhook
var err *model.AppError appErr *model.AppError
)
if channelId != "" { if channelID != "" {
if !c.App.SessionHasPermissionToChannel(c.AppContext, *c.AppContext.Session(), channelId, model.PermissionManageOutgoingWebhooks) { if !c.App.SessionHasPermissionToChannel(c.AppContext, *c.AppContext.Session(), channelID, model.PermissionManageOutgoingWebhooks) {
c.SetPermissionError(model.PermissionManageOutgoingWebhooks) c.SetPermissionError(model.PermissionManageOutgoingWebhooks)
return return
} }
// Remove userId as a filter if they have permission to manage others. // Remove userId as a filter if they have permission to manage others.
if c.App.SessionHasPermissionToChannel(c.AppContext, *c.AppContext.Session(), channelId, model.PermissionManageOthersOutgoingWebhooks) { if c.App.SessionHasPermissionToChannel(c.AppContext, *c.AppContext.Session(), channelID, model.PermissionManageOthersOutgoingWebhooks) {
userId = "" userID = ""
} }
hooks, err = c.App.GetOutgoingWebhooksForChannelPageByUser(channelId, userId, c.Params.Page, c.Params.PerPage) hooks, appErr = c.App.GetOutgoingWebhooksForChannelPageByUser(channelID, userID, c.Params.Page, c.Params.PerPage)
} else if teamId != "" { } else if teamID != "" {
if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), teamId, model.PermissionManageOutgoingWebhooks) { if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), teamID, model.PermissionManageOutgoingWebhooks) {
c.SetPermissionError(model.PermissionManageOutgoingWebhooks) c.SetPermissionError(model.PermissionManageOutgoingWebhooks)
return return
} }
// Remove userId as a filter if they have permission to manage others. // Remove userId as a filter if they have permission to manage others.
if c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), teamId, model.PermissionManageOthersOutgoingWebhooks) { if c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), teamID, model.PermissionManageOthersOutgoingWebhooks) {
userId = "" 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 { } else {
if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageOutgoingWebhooks) { if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageOutgoingWebhooks) {
c.SetPermissionError(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. // Remove userId as a filter if they have permission to manage others.
if c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageOthersOutgoingWebhooks) { 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 { if err != nil {
c.Err = err c.Err = model.NewAppError("getOutgoingHooks", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
return 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) w.Write(js)
} }

Просмотреть файл

@@ -7,7 +7,6 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"net/http" "net/http"
"os" "os"
"runtime/debug" "runtime/debug"
@@ -29,7 +28,7 @@ func (s *Server) GetLogs(page, perPage int) ([]string, *model.AppError) {
var lines []string var lines []string
license := s.License() 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 { if info := s.Cluster.GetMyClusterInfo(); info != nil {
lines = append(lines, "-----------------------------------------------------------------------------------------------------------") lines = append(lines, "-----------------------------------------------------------------------------------------------------------")
lines = append(lines, "-----------------------------------------------------------------------------------------------------------") lines = append(lines, "-----------------------------------------------------------------------------------------------------------")
@@ -48,7 +47,7 @@ func (s *Server) GetLogs(page, perPage int) ([]string, *model.AppError) {
lines = append(lines, melines...) 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) clines, err := s.Cluster.GetLogs(page, perPage)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -67,9 +66,9 @@ func (a *App) GetLogs(page, perPage int) ([]string, *model.AppError) {
func (s *Server) GetLogsSkipSend(page, perPage int) ([]string, *model.AppError) { func (s *Server) GetLogsSkipSend(page, perPage int) ([]string, *model.AppError) {
var lines []string var lines []string
if *s.Config().LogSettings.EnableFile { if *s.platform.Config().LogSettings.EnableFile {
s.Log.Flush() s.Log.Flush()
logFile := config.GetLogFileLocation(*s.Config().LogSettings.FileLocation) logFile := config.GetLogFileLocation(*s.platform.Config().LogSettings.FileLocation)
file, err := os.Open(logFile) file, err := os.Open(logFile)
if err != nil { if err != nil {
return nil, model.NewAppError("getLogs", "api.admin.file_read_error", nil, err.Error(), http.StatusInternalServerError) return nil, model.NewAppError("getLogs", "api.admin.file_read_error", nil, err.Error(), http.StatusInternalServerError)
@@ -261,7 +260,7 @@ func (a *App) GetLatestVersion(latestVersionUrl string) (*model.GithubReleaseInf
defer res.Body.Close() defer res.Body.Close()
responseData, err := ioutil.ReadAll(res.Body) responseData, err := io.ReadAll(res.Body)
if err != nil { if err != nil {
return nil, model.NewAppError("GetLatestVersion", "app.admin.latest_version_read_all.failure", nil, "", http.StatusInternalServerError) return nil, model.NewAppError("GetLatestVersion", "app.admin.latest_version_read_all.failure", nil, "", http.StatusInternalServerError)
} }

Просмотреть файл

@@ -283,6 +283,8 @@ type AppIface interface {
// PromoteGuestToUser Convert user's roles and all his membership's roles from // PromoteGuestToUser Convert user's roles and all his membership's roles from
// guest roles to regular user roles. // guest roles to regular user roles.
PromoteGuestToUser(c *request.Context, user *model.User, requestorId string) *model.AppError 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 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) 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 // RenameTeam is used to rename the team Name and the DisplayName fields
@@ -942,7 +944,6 @@ type AppIface interface {
ReloadConfig() error ReloadConfig() error
RemoveAllDeactivatedMembersFromChannel(c request.CTX, channel *model.Channel) *model.AppError RemoveAllDeactivatedMembersFromChannel(c request.CTX, channel *model.Channel) *model.AppError
RemoveChannelsFromRetentionPolicy(policyID string, channelIDs []string) *model.AppError RemoveChannelsFromRetentionPolicy(policyID string, channelIDs []string) *model.AppError
RemoveConfigListener(id string)
RemoveCustomStatus(c request.CTX, userID string) *model.AppError RemoveCustomStatus(c request.CTX, userID string) *model.AppError
RemoveDirectory(path string) *model.AppError RemoveDirectory(path string) *model.AppError
RemoveFile(path string) *model.AppError RemoveFile(path string) *model.AppError

Просмотреть файл

@@ -109,10 +109,10 @@ func (s *Server) configureAudit(adt *audit.Audit, bAllowAdvancedLogging bool) er
adt.OnError = s.onAuditError adt.OnError = s.onAuditError
var logConfigSrc config.LogConfigSrc var logConfigSrc config.LogConfigSrc
dsn := *s.Config().ExperimentalAuditSettings.AdvancedLoggingConfig dsn := *s.platform.Config().ExperimentalAuditSettings.AdvancedLoggingConfig
if bAllowAdvancedLogging && dsn != "" { if bAllowAdvancedLogging && dsn != "" {
var err error var err error
logConfigSrc, err = config.NewLogConfigSrc(dsn, s.configStore.Store) logConfigSrc, err = config.NewLogConfigSrc(dsn, s.platform.GetConfigStore())
if err != nil { if err != nil {
return fmt.Errorf("invalid config source for audit, %w", err) 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). // 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 { if err != nil {
return fmt.Errorf("invalid config for audit, %w", err) return fmt.Errorf("invalid config for audit, %w", err)
} }

Просмотреть файл

@@ -7,7 +7,7 @@ import (
"context" "context"
"encoding/csv" "encoding/csv"
"fmt" "fmt"
"io/ioutil" "io"
"os" "os"
"strconv" "strconv"
"strings" "strings"
@@ -133,7 +133,7 @@ func TestSessionHasPermissionToGroup(t *testing.T) {
require.NoError(t, e) require.NoError(t, e)
defer file.Close() defer file.Close()
b, e := ioutil.ReadAll(file) b, e := io.ReadAll(file)
require.NoError(t, e) require.NoError(t, e)
r := csv.NewReader(strings.NewReader(string(b))) r := csv.NewReader(strings.NewReader(string(b)))

Просмотреть файл

@@ -641,11 +641,11 @@ func (a *App) UpdateChannel(c request.CTX, channel *model.Channel) (*model.Chann
var invErr *store.ErrInvalidInput var invErr *store.ErrInvalidInput
switch { switch {
case errors.As(err, &invErr): 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): case errors.As(err, &appErr):
return nil, appErr return nil, appErr
default: 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): case errors.As(err, &appErr):
return nil, appErr return nil, appErr
case errors.As(err, &nfErr): 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: 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) { func (a *App) updateChannelMember(c request.CTX, member *model.ChannelMember) (*model.ChannelMember, *model.AppError) {
member, nErr := a.Srv().Store.Channel().UpdateMember(member) member, err := a.Srv().Store.Channel().UpdateMember(member)
if nErr != nil { if err != nil {
var appErr *model.AppError var appErr *model.AppError
var nfErr *store.ErrNotFound var nfErr *store.ErrNotFound
switch { switch {
case errors.As(nErr, &appErr): case errors.As(err, &appErr):
return nil, appErr return nil, appErr
case errors.As(nErr, &nfErr): case errors.As(err, &nfErr):
return nil, model.NewAppError("updateChannelMember", MissingChannelMemberError, nil, nfErr.Error(), http.StatusNotFound) return nil, model.NewAppError("updateChannelMember", MissingChannelMemberError, nil, "", http.StatusNotFound).Wrap(nfErr)
default: 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) { func (a *App) markChannelAsUnreadFromPostCRTUnsupported(c request.CTX, postID string, userID string) (*model.ChannelUnreadAt, *model.AppError) {
post, err := a.GetSinglePost(postID, false) post, appErr := a.GetSinglePost(postID, false)
if err != nil { if appErr != nil {
return nil, err return nil, appErr
} }
user, err := a.GetUser(userID) user, appErr := a.GetUser(userID)
if err != nil { if appErr != nil {
return nil, err return nil, appErr
} }
threadId := post.RootId threadId := post.RootId
@@ -2619,18 +2619,18 @@ func (a *App) markChannelAsUnreadFromPostCRTUnsupported(c request.CTX, postID st
threadId = post.Id threadId = post.Id
} }
unreadMentions, unreadMentionsRoot, err := a.countMentionsFromPost(c, user, post) unreadMentions, unreadMentionsRoot, appErr := a.countMentionsFromPost(c, user, post)
if err != nil { if appErr != nil {
return nil, err return nil, appErr
} }
// if root post, // 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 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. // 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 == "" { if post.RootId == "" {
channelUnread, nErr := a.Srv().Store.Channel().UpdateLastViewedAtPost(post, userID, unreadMentions, unreadMentionsRoot, true) channelUnread, err := a.Srv().Store.Channel().UpdateLastViewedAtPost(post, userID, unreadMentions, unreadMentionsRoot, true)
if nErr != nil { if err != nil {
return channelUnread, model.NewAppError("MarkChannelAsUnreadFromPost", "app.channel.update_last_viewed_at_post.app_error", nil, nErr.Error(), http.StatusInternalServerError) 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) 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. // 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. // 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. // 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) rootPost, appErr := a.GetSinglePost(post.RootId, false)
if err != nil { if appErr != nil {
return nil, err return nil, appErr
} }
channel, nErr := a.Srv().Store.Channel().Get(post.ChannelId, true) channel, err := a.Srv().Store.Channel().Get(post.ChannelId, true)
if nErr != nil { if err != nil {
return nil, model.NewAppError("MarkChannelAsUnreadFromPost", "app.channel.update_last_viewed_at_post.app_error", nil, nErr.Error(), http.StatusInternalServerError) return nil, model.NewAppError("MarkChannelAsUnreadFromPost", "app.channel.update_last_viewed_at_post.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
} }
if *a.Config().ServiceSettings.ThreadAutoFollow { 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 var errNotFound *store.ErrNotFound
if sErr != nil && !errors.As(sErr, &errNotFound) { if mErr != nil && !errors.As(mErr, &errNotFound) {
return nil, model.NewAppError("MarkChannelAsUnreadFromPost", "app.channel.update_last_viewed_at_post.app_error", nil, sErr.Error(), http.StatusInternalServerError) 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 // Follow thread if we're not already following it
if threadMembership == nil { if threadMembership == nil {
@@ -2668,25 +2668,25 @@ func (a *App) markChannelAsUnreadFromPostCRTUnsupported(c request.CTX, postID st
UpdateViewedTimestamp: false, UpdateViewedTimestamp: false,
UpdateParticipants: false, UpdateParticipants: false,
} }
threadMembership, sErr = a.Srv().Store.Thread().MaintainMembership(user.Id, threadId, opts) threadMembership, mErr = a.Srv().Store.Thread().MaintainMembership(user.Id, threadId, opts)
if sErr != nil { if mErr != nil {
return nil, model.NewAppError("MarkChannelAsUnreadFromPost", "app.channel.update_last_viewed_at_post.app_error", nil, sErr.Error(), http.StatusInternalServerError) 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. // If threadmembership already exists but user had previously unfollowed the thread, then follow the thread again.
threadMembership.Following = true threadMembership.Following = true
threadMembership.LastViewed = post.CreateAt - 1 threadMembership.LastViewed = post.CreateAt - 1
threadMembership.UnreadMentions, err = a.countThreadMentions(c, user, rootPost, channel.TeamId, post.CreateAt-1) threadMembership.UnreadMentions, appErr = a.countThreadMentions(c, user, rootPost, channel.TeamId, post.CreateAt-1)
if err != nil { if appErr != nil {
return nil, err return nil, appErr
} }
threadMembership, sErr = a.Srv().Store.Thread().UpdateMembership(threadMembership) threadMembership, mErr = a.Srv().Store.Thread().UpdateMembership(threadMembership)
if sErr != nil { if mErr != nil {
return nil, model.NewAppError("MarkChannelAsUnreadFromPost", "app.channel.update_last_viewed_at_post.app_error", nil, sErr.Error(), http.StatusInternalServerError) 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) thread, mErr := a.Srv().Store.Thread().GetThreadForUser(channel.TeamId, threadMembership, true)
if sErr != nil { if mErr != nil {
return nil, model.NewAppError("MarkChannelAsUnreadFromPost", "app.channel.update_last_viewed_at_post.app_error", nil, sErr.Error(), http.StatusInternalServerError) return nil, model.NewAppError("MarkChannelAsUnreadFromPost", "app.channel.update_last_viewed_at_post.app_error", nil, "", http.StatusInternalServerError).Wrap(mErr)
} }
a.sanitizeProfiles(thread.Participants, false) a.sanitizeProfiles(thread.Participants, false)
thread.Post.SanitizeProps() 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) channelUnread, err := a.Srv().Store.Channel().UpdateLastViewedAtPost(post, userID, unreadMentions, 0, false)
if nErr != nil { if err != nil {
return channelUnread, model.NewAppError("MarkChannelAsUnreadFromPost", "app.channel.update_last_viewed_at_post.app_error", nil, nErr.Error(), http.StatusInternalServerError) 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.sendWebSocketPostUnreadEvent(c, channelUnread, postID, false)
a.UpdateMobileAppBadge(userID) 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) { 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) members, err := a.Srv().Store.Channel().GetMembersByChannelIds(channelIDs, userID)
if nErr != nil { if err != nil {
var appErr *model.AppError var appErr *model.AppError
switch { switch {
case errors.As(nErr, &appErr): case errors.As(err, &appErr):
return nil, appErr return nil, appErr
default: 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 return nil, nil
} }
updated, nErr := a.Srv().Store.Channel().UpdateMultipleMembers(membersToUpdate) updated, err := a.Srv().Store.Channel().UpdateMultipleMembers(membersToUpdate)
if nErr != nil { if err != nil {
var appErr *model.AppError var appErr *model.AppError
var nfErr *store.ErrNotFound var nfErr *store.ErrNotFound
switch { switch {
case errors.As(nErr, &appErr): case errors.As(err, &appErr):
return nil, appErr return nil, appErr
case errors.As(nErr, &nfErr): case errors.As(err, &nfErr):
return nil, model.NewAppError("setChannelsMuted", MissingChannelMemberError, nil, nfErr.Error(), http.StatusNotFound) return nil, model.NewAppError("setChannelsMuted", MissingChannelMemberError, nil, "", http.StatusNotFound).Wrap(nfErr)
default: 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 return nil
} }
if err := a.forEachChannelMember(c, channelID, clearSessionCache); err != 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 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) { 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) channelMemberCounts, err := a.Srv().Store.Channel().GetMemberCountsByGroup(ctx, channelID, includeTimezones)
if err != nil { 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 return channelMemberCounts, nil

Просмотреть файл

@@ -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) { 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) updatedCategories, originalCategories, err := a.Srv().Store.Channel().UpdateSidebarCategories(userID, teamID, categories)
if err != nil { 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) message := model.NewWebSocketEvent(model.WebsocketEventSidebarCategoryUpdated, teamID, "", userID, nil)

Просмотреть файл

@@ -2056,7 +2056,7 @@ func TestMarkChannelsAsViewedPanic(t *testing.T) {
UserStore: &mockUserStore, UserStore: &mockUserStore,
SessionStore: &mockSessionStore, SessionStore: &mockSessionStore,
OAuthStore: &mockOAuthStore, OAuthStore: &mockOAuthStore,
ConfigFn: th.App.ch.srv.Config, ConfigFn: th.App.ch.srv.platform.Config,
LicenseFn: th.App.ch.srv.License, LicenseFn: th.App.ch.srv.License,
}) })
require.NoError(t, err) require.NoError(t, err)

Просмотреть файл

@@ -31,12 +31,6 @@ type licenseSvc interface {
RequestTrialLicense(requesterID string, users int, termsAccepted bool, receiveEmailsAccepted bool) *model.AppError 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. // Channels contains all channels related state.
type Channels struct { type Channels struct {
srv *Server srv *Server
@@ -107,7 +101,7 @@ func init() {
func NewChannels(s *Server, services map[ServiceKey]any) (*Channels, error) { func NewChannels(s *Server, services map[ServiceKey]any) (*Channels, error) {
ch := &Channels{ ch := &Channels{
srv: s, srv: s,
imageProxy: imageproxy.MakeImageProxy(s, s.httpService, s.Log), imageProxy: imageproxy.MakeImageProxy(s.platform, s.httpService, s.Log),
uploadLockMap: map[string]bool{}, uploadLockMap: map[string]bool{},
} }
@@ -133,10 +127,6 @@ func NewChannels(s *Server, services map[ServiceKey]any) (*Channels, error) {
if !ok { if !ok {
return nil, errors.New("Config service did not satisfy ConfigSvc interface") 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 ch.cfgSvc = cfgSvc
case FilestoreKey: case FilestoreKey:
filestore, ok := svc.(filestore.FileBackend) filestore, ok := svc.(filestore.FileBackend)
@@ -149,10 +139,6 @@ func NewChannels(s *Server, services map[ServiceKey]any) (*Channels, error) {
if !ok { if !ok {
return nil, errors.New("License service did not satisfy licenseSvc interface") 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 ch.licenseSvc = svc
} }
} }

Просмотреть файл

@@ -83,7 +83,7 @@ func (cds *ClusterDiscoveryService) Stop() {
} }
func (s *Server) IsLeader() bool { 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 s.Cluster.IsLeader()
} }
return true return true

Просмотреть файл

@@ -7,7 +7,6 @@ import (
"context" "context"
"errors" "errors"
"io" "io"
"io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
"regexp" "regexp"
@@ -521,7 +520,7 @@ func (a *App) DoCommandRequest(cmd *model.Command, p url.Values) (*model.Command
if resp.StatusCode != http.StatusOK { if resp.StatusCode != http.StatusOK {
// Ignore the error below because the resulting string will just be the empty string if bodyBytes is nil // 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) 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)
} }

Просмотреть файл

@@ -280,7 +280,7 @@ func (a *App) getDynamicListArgument(c *request.Context, commandArgs *model.Comm
var listItems []model.AutocompleteListItem var listItems []model.AutocompleteListItem
if jsonErr := json.NewDecoder(resp.Body).Decode(&listItems); jsonErr != nil { 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) return parseListItems(listItems, parsed, toBeParsed)

Просмотреть файл

@@ -5,8 +5,8 @@ package app
import ( import (
"errors" "errors"
"io/ioutil"
"net/http" "net/http"
"os"
"github.com/mattermost/mattermost-server/v6/model" "github.com/mattermost/mattermost-server/v6/model"
"github.com/mattermost/mattermost-server/v6/shared/mlog" "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) { 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 { if err != nil {
return nil, model.NewAppError("readFile", "api.file.read_file.reading_local.app_error", nil, err.Error(), http.StatusNotImplemented) return nil, model.NewAppError("readFile", "api.file.read_file.reading_local.app_error", nil, err.Error(), http.StatusNotImplemented)
} }

Просмотреть файл

@@ -12,7 +12,6 @@ import (
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/http"
"net/url" "net/url"
"reflect" "reflect"
"strconv" "strconv"
@@ -22,7 +21,6 @@ import (
"github.com/mattermost/mattermost-server/v6/config" "github.com/mattermost/mattermost-server/v6/config"
"github.com/mattermost/mattermost-server/v6/model" "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/mail"
"github.com/mattermost/mattermost-server/v6/shared/mlog" "github.com/mattermost/mattermost-server/v6/shared/mlog"
"github.com/mattermost/mattermost-server/v6/utils" "github.com/mattermost/mattermost-server/v6/utils"
@@ -32,113 +30,24 @@ const (
ErrorTermsOfServiceNoRowsFound = "app.terms_of_service.get.no_rows.app_error" 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 { func (s *Server) Config() *model.Config {
return s.configStore.Config() return s.platform.Config()
}
func (s *Server) ConfigStore() *configWrapper {
return s.configStore
} }
func (a *App) Config() *model.Config { func (a *App) Config() *model.Config {
return a.ch.cfgSvc.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 { func (a *App) EnvironmentConfig(filter func(reflect.StructField) bool) map[string]any {
return a.Srv().EnvironmentConfig(filter) return a.Srv().platform.GetEnvironmentOverridesWithFilter(filter)
}
func (s *Server) UpdateConfig(f func(*model.Config)) {
s.configStore.UpdateConfig(f)
} }
func (a *App) UpdateConfig(f func(*model.Config)) { func (a *App) UpdateConfig(f func(*model.Config)) {
a.Srv().UpdateConfig(f) a.Srv().platform.UpdateConfig(f)
}
func (s *Server) ReloadConfig() error {
return s.configStore.ReloadConfig()
} }
func (a *App) ReloadConfig() error { func (a *App) ReloadConfig() error {
return a.Srv().ReloadConfig() return a.Srv().platform.ReloadConfig()
} }
func (a *App) ClientConfig() map[string]string { 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) 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 { 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 // 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) { func (a *App) RemoveConfigListener(id string) {
a.Srv().RemoveConfigListener(id) a.Srv().platform.RemoveConfigListener(id)
} }
// ensurePostActionCookieSecret ensures that the key for encrypting PostActionCookie exists // 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. // GetConfigFile proxies access to the given configuration file to the underlying config store.
func (a *App) GetConfigFile(name string) ([]byte, error) { 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 { if err != nil {
return nil, errors.Wrapf(err, "failed to get config file %s", name) 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) 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. // SaveConfig replaces the active configuration, optionally notifying cluster peers.
func (a *App) SaveConfig(newCfg *model.Config, sendConfigChangeClusterMessage bool) (*model.Config, *model.Config, *model.AppError) { 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) { 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 { func (s *Server) MailServiceConfig() *mail.SMTPConfig {
emailSettings := s.Config().EmailSettings emailSettings := s.platform.Config().EmailSettings
hostname := utils.GetHostnameFromSiteURL(*s.Config().ServiceSettings.SiteURL) hostname := utils.GetHostnameFromSiteURL(*s.platform.Config().ServiceSettings.SiteURL)
cfg := mail.SMTPConfig{ cfg := mail.SMTPConfig{
Hostname: hostname, Hostname: hostname,
ConnectionSecurity: *emailSettings.ConnectionSecurity, ConnectionSecurity: *emailSettings.ConnectionSecurity,

Просмотреть файл

@@ -16,41 +16,6 @@ import (
"github.com/mattermost/mattermost-server/v6/utils" "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) { func TestAsymmetricSigningKey(t *testing.T) {
th := SetupWithStoreMock(t) th := SetupWithStoreMock(t)
defer th.TearDown() defer th.TearDown()

Просмотреть файл

@@ -5,7 +5,6 @@ package app
import ( import (
"io" "io"
"io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
"time" "time"
@@ -35,7 +34,7 @@ func (s *Server) downloadFromURL(downloadURL string) ([]byte, error) {
if err != nil { if err != nil {
return nil, errors.Errorf("failed to parse url %s", downloadURL) 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) return nil, errors.Errorf("insecure url not allowed %s", downloadURL)
} }
@@ -64,5 +63,5 @@ func (s *Server) downloadFromURL(downloadURL string) ([]byte, error) {
defer resp.Body.Close() defer resp.Body.Close()
return ioutil.ReadAll(resp.Body) return io.ReadAll(resp.Body)
} }

Просмотреть файл

@@ -5,7 +5,6 @@ package email
import ( import (
"bytes" "bytes"
"io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"testing" "testing"
@@ -64,7 +63,7 @@ func SetupWithStoreMock(tb testing.TB) *TestHelper {
} }
func setupTestHelper(s store.Store, 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 { if err != nil {
panic(err) panic(err)
} }

Просмотреть файл

@@ -39,11 +39,11 @@ const (
func (a *App) CreateEmoji(sessionUserId string, emoji *model.Emoji, multiPartImageData *multipart.Form) (*model.Emoji, *model.AppError) { func (a *App) CreateEmoji(sessionUserId string, emoji *model.Emoji, multiPartImageData *multipart.Form) (*model.Emoji, *model.AppError) {
if !*a.Config().ServiceSettings.EnableCustomEmoji { 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 == "" { 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 // wipe the emoji id so that existing emojis can't get overwritten
@@ -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 // 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 // orphaned files left over when validation fails later on
emoji.PreSave() emoji.PreSave()
if err := emoji.IsValid(); err != nil { if appErr := emoji.IsValid(); appErr != nil {
return nil, err return nil, appErr
} }
if emoji.CreatorId != sessionUserId { 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 { 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"] imageData := multiPartImageData.File["image"]
if len(imageData) == 0 { if len(imageData) == 0 {
err := model.NewAppError("Context", "api.context.invalid_body_param.app_error", map[string]any{"Name": "createEmoji"}, "", http.StatusBadRequest) return nil, model.NewAppError("Context", "api.context.invalid_body_param.app_error", map[string]any{"Name": "createEmoji"}, "", http.StatusBadRequest)
return nil, err
} }
if err := a.UploadEmojiImage(emoji.Id, imageData[0]); err != nil { if appErr := a.UploadEmojiImage(emoji.Id, imageData[0]); appErr != nil {
return nil, err return nil, appErr
} }
emoji, err := a.Srv().Store.Emoji().Save(emoji) emoji, err := a.Srv().Store.Emoji().Save(emoji)
if err != nil { 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) message := model.NewWebSocketEvent(model.WebsocketEventEmojiAdded, "", "", "", nil)
@@ -100,11 +99,11 @@ func (a *App) GetEmojiList(page, perPage int, sort string) ([]*model.Emoji, *mod
func (a *App) UploadEmojiImage(id string, imageData *multipart.FileHeader) *model.AppError { func (a *App) UploadEmojiImage(id string, imageData *multipart.FileHeader) *model.AppError {
if !*a.Config().ServiceSettings.EnableCustomEmoji { 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 == "" { 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() file, err := imageData.Open()
@@ -185,11 +184,11 @@ func (a *App) DeleteEmoji(emoji *model.Emoji) *model.AppError {
func (a *App) GetEmoji(emojiId string) (*model.Emoji, *model.AppError) { func (a *App) GetEmoji(emojiId string) (*model.Emoji, *model.AppError) {
if !*a.Config().ServiceSettings.EnableCustomEmoji { 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 == "" { 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) emoji, err := a.Srv().Store.Emoji().Get(context.Background(), emojiId, true)
@@ -208,11 +207,11 @@ func (a *App) GetEmoji(emojiId string) (*model.Emoji, *model.AppError) {
func (a *App) GetEmojiByName(emojiName string) (*model.Emoji, *model.AppError) { func (a *App) GetEmojiByName(emojiName string) (*model.Emoji, *model.AppError) {
if !*a.Config().ServiceSettings.EnableCustomEmoji { 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 == "" { 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) emoji, err := a.Srv().Store.Emoji().GetByName(context.Background(), emojiName, true)
@@ -231,7 +230,7 @@ func (a *App) GetEmojiByName(emojiName string) (*model.Emoji, *model.AppError) {
func (a *App) GetMultipleEmojiByName(names []string) ([]*model.Emoji, *model.AppError) { func (a *App) GetMultipleEmojiByName(names []string) ([]*model.Emoji, *model.AppError) {
if !*a.Config().ServiceSettings.EnableCustomEmoji { 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) emoji, err := a.Srv().Store.Emoji().GetMultipleByName(names)
@@ -269,7 +268,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) { func (a *App) SearchEmoji(name string, prefixOnly bool, limit int) ([]*model.Emoji, *model.AppError) {
if !*a.Config().ServiceSettings.EnableCustomEmoji { 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) list, err := a.Srv().Store.Emoji().Search(name, prefixOnly, limit)

Просмотреть файл

@@ -87,9 +87,9 @@ func RegisterCloudInterface(f func(*Server) einterfaces.CloudInterface) {
cloudInterface = f 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 metricsInterface = f
} }

Просмотреть файл

@@ -141,14 +141,14 @@ func (a *App) BulkExport(ctx request.CTX, writer io.Writer, outPath string, opts
return nil 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) b, err := json.Marshal(line)
if err != nil { 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 { if _, err := w.Write(append(b, '\n')); err != nil {
return model.NewAppError("BulkExport", "app.export.export_write_line.io_writer.error", nil, "err="+err.Error(), http.StatusBadRequest) return model.NewAppError("BulkExport", "app.export.export_write_line.io_writer.error", nil, "", http.StatusBadRequest).Wrap(err)
} }
return nil return nil

Просмотреть файл

@@ -6,7 +6,6 @@ package app
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"sort" "sort"
@@ -590,7 +589,7 @@ func TestBulkExport(t *testing.T) {
th := Setup(t) th := Setup(t)
testsDir, _ := fileutils.FindDir("tests") testsDir, _ := fileutils.FindDir("tests")
dir, err := ioutil.TempDir("", "import_test") dir, err := os.MkdirTemp("", "import_test")
require.NoError(t, err) require.NoError(t, err)
defer os.RemoveAll(dir) defer os.RemoveAll(dir)

Просмотреть файл

@@ -8,7 +8,6 @@ import (
"bytes" "bytes"
"compress/gzip" "compress/gzip"
"fmt" "fmt"
"io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"sort" "sort"
@@ -81,7 +80,7 @@ func TestExtractTarGz(t *testing.T) {
}) })
} }
dst, err := ioutil.TempDir("", "TestExtractTarGz") dst, err := os.MkdirTemp("", "TestExtractTarGz")
require.NoError(t, err) require.NoError(t, err)
defer os.RemoveAll(dst) defer os.RemoveAll(dst)
@@ -175,7 +174,7 @@ func TestExtractTarGz(t *testing.T) {
for i, testCase := range testCases { for i, testCase := range testCases {
t.Run(fmt.Sprintf("test-%d", i), func(t *testing.T) { 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) require.NoError(t, err)
defer os.RemoveAll(dst) defer os.RemoveAll(dst)

Просмотреть файл

@@ -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
}
}

Просмотреть файл

@@ -122,9 +122,9 @@ func (a *App) isUniqueToUsernames(val string) *model.AppError {
} }
func (a *App) CreateGroupWithUserIds(group *model.GroupWithUserIds) (*model.Group, *model.AppError) { func (a *App) CreateGroupWithUserIds(group *model.GroupWithUserIds) (*model.Group, *model.AppError) {
if err := a.isUniqueToUsernames(group.GetName()); err != nil { if appErr := a.isUniqueToUsernames(group.GetName()); appErr != nil {
err.Where = "CreateGroupWithUserIds" appErr.Where = "CreateGroupWithUserIds"
return nil, err return nil, appErr
} }
newGroup, err := a.Srv().Store.Group().CreateWithUserIds(group) 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): case errors.As(err, &appErr):
return nil, appErr return nil, appErr
case errors.As(err, &invErr): 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): 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: 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) messageWs := model.NewWebSocketEvent(model.WebsocketEventReceivedGroup, "", "", "", nil)
count, err := a.Srv().Store.Group().GetMemberCount(newGroup.Id) count, err := a.Srv().Store.Group().GetMemberCount(newGroup.Id)
if err != nil { 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)) group.MemberCount = model.NewInt(int(count))
groupJSON, jsonErr := json.Marshal(newGroup) 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) { func (a *App) UpdateGroup(group *model.Group) (*model.Group, *model.AppError) {
if err := a.isUniqueToUsernames(group.GetName()); err != nil { if appErr := a.isUniqueToUsernames(group.GetName()); appErr != nil {
err.Where = "UpdateGroup" appErr.Where = "UpdateGroup"
return nil, err return nil, appErr
} }
updatedGroup, err := a.Srv().Store.Group().Update(group) 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 { if err != nil {
var nfErr *store.ErrNotFound var nfErr *store.ErrNotFound
var appErr *model.AppError var appErr *model.AppError
@@ -191,14 +175,29 @@ func (a *App) UpdateGroup(group *model.Group) (*model.Group, *model.AppError) {
case errors.As(err, &appErr): case errors.As(err, &appErr):
return nil, appErr return nil, appErr
case errors.As(err, &nfErr): 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): 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: 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 return updatedGroup, nil
} }
@@ -763,9 +762,9 @@ func (a *App) DeleteGroupMembers(groupID string, userIDs []string) ([]*model.Gro
case errors.As(err, &appErr): case errors.As(err, &appErr):
return nil, appErr return nil, appErr
case errors.As(err, &invErr): 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: 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)
} }
} }

Просмотреть файл

@@ -5,7 +5,6 @@ package app
import ( import (
"context" "context"
"io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
@@ -48,7 +47,7 @@ type TestHelper struct {
} }
func setupTestHelper(dbStore store.Store, enterprise bool, includeCacheLayer bool, options []Option, tb testing.TB) *TestHelper { 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 { if err != nil {
panic(err) panic(err)
} }

Просмотреть файл

@@ -6,7 +6,6 @@ package imaging
import ( import (
"bytes" "bytes"
"image/color" "image/color"
"io/ioutil"
"os" "os"
"testing" "testing"
@@ -77,7 +76,7 @@ func TestFillImageTransparency(t *testing.T) {
require.NotNil(t, inputImg) require.NotNil(t, inputImg)
require.Equal(t, "png", format) require.Equal(t, "png", format)
expectedBytes, err := ioutil.ReadFile(imgDir + "/" + tc.outputName) expectedBytes, err := os.ReadFile(imgDir + "/" + tc.outputName)
require.NoError(t, err) require.NoError(t, err)
FillImageTransparency(inputImg, tc.fillColor) FillImageTransparency(inputImg, tc.fillColor)

Просмотреть файл

@@ -10,7 +10,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"net/http" "net/http"
"os" "os"
"path" "path"
@@ -1217,7 +1216,7 @@ func (a *App) importAttachment(c *request.Context, data *AttachmentImportData, p
timestamp := utils.TimeFromMillis(post.CreateAt) timestamp := utils.TimeFromMillis(post.CreateAt)
fileData, err := ioutil.ReadAll(file) fileData, err := io.ReadAll(file)
if err != nil { if err != nil {
return nil, model.NewAppError("BulkImport", "app.import.attachment.read_file_data.error", map[string]any{"FilePath": *data.Path}, "", http.StatusBadRequest) return nil, model.NewAppError("BulkImport", "app.import.attachment.read_file_data.error", map[string]any{"FilePath": *data.Path}, "", http.StatusBadRequest)
} }

Просмотреть файл

@@ -6,7 +6,6 @@ package app
import ( import (
"archive/zip" "archive/zip"
"context" "context"
"io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
@@ -3100,7 +3099,6 @@ func TestImportImportPost(t *testing.T) {
}) })
t.Run("Reply CreateAt before parent post CreateAt", func(t *testing.T) { t.Run("Reply CreateAt before parent post CreateAt", func(t *testing.T) {
t.Skip("MM-44922")
now := model.GetMillis() now := model.GetMillis()
before := now - 10 before := now - 10
data := LineImportWorkerData{ data := LineImportWorkerData{
@@ -3128,6 +3126,7 @@ func TestImportImportPost(t *testing.T) {
posts, nErr := th.App.Srv().Store.Post().GetPostsCreatedAt(channel.Id, now) posts, nErr := th.App.Srv().Store.Post().GetPostsCreatedAt(channel.Id, now)
require.NoError(t, nErr) require.NoError(t, nErr)
require.Len(t, posts, 2, "Unexpected number of posts found.") 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") testlib.AssertLog(t, th.LogBuffer, mlog.LvlWarn.Name, "Reply CreateAt is before parent post CreateAt, setting it to parent post CreateAt")
rootPost := posts[0] rootPost := posts[0]
@@ -4378,11 +4377,11 @@ func TestImportDirectPostWithAttachments(t *testing.T) {
testImage := filepath.Join(testsDir, "test.png") testImage := filepath.Join(testsDir, "test.png")
testImage2 := filepath.Join(testsDir, "test.svg") testImage2 := filepath.Join(testsDir, "test.svg")
// create a temp file with same name as original but with a different first byte // 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") testImageFake := filepath.Join(tmpFolder, "test.png")
fakeFileData, _ := ioutil.ReadFile(testImage) fakeFileData, _ := os.ReadFile(testImage)
fakeFileData[0] = 0 fakeFileData[0] = 0
_ = ioutil.WriteFile(testImageFake, fakeFileData, 0644) _ = os.WriteFile(testImageFake, fakeFileData, 0644)
defer os.RemoveAll(tmpFolder) defer os.RemoveAll(tmpFolder)
// Create a user. // Create a user.

Просмотреть файл

@@ -6,7 +6,6 @@ package app
import ( import (
"archive/zip" "archive/zip"
"io" "io"
"io/ioutil"
"net/http" "net/http"
"os" "os"
"path/filepath" "path/filepath"
@@ -439,7 +438,7 @@ func BenchmarkBulkImport(b *testing.B) {
info, err := importFile.Stat() info, err := importFile.Stat()
require.NoError(b, err) require.NoError(b, err)
dir, err := ioutil.TempDir("", "testimport") dir, err := os.MkdirTemp("", "testimport")
require.NoError(b, err) require.NoError(b, err)
defer os.RemoveAll(dir) defer os.RemoveAll(dir)

Просмотреть файл

@@ -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 var unused map[string]string
if err := json.NewDecoder(strings.NewReader(*tdata.Theme)).Decode(&unused); err != nil { 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)
} }
} }
} }

Просмотреть файл

@@ -23,7 +23,7 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"io/ioutil" "io"
"net/http" "net/http"
"net/url" "net/url"
"path" "path"
@@ -98,9 +98,9 @@ func (a *App) DoPostActionWithCookie(c *request.Context, postID, actionId, userI
var nfErr *store.ErrNotFound var nfErr *store.ErrNotFound
switch { switch {
case errors.As(result.NErr, &nfErr): 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: 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 { if cookie.Integration == nil {
@@ -116,9 +116,9 @@ func (a *App) DoPostActionWithCookie(c *request.Context, postID, actionId, userI
var nfErr *store.ErrNotFound var nfErr *store.ErrNotFound
switch { switch {
case errors.As(err, &nfErr): 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: 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) post := result.Data.(*model.Post)
result = <-cchan result = <-cchan
if result.NErr != nil { 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) channel := result.Data.(*model.Channel)
@@ -195,9 +195,9 @@ func (a *App) DoPostActionWithCookie(c *request.Context, postID, actionId, userI
var nfErr *store.ErrNotFound var nfErr *store.ErrNotFound
switch { switch {
case errors.As(ur.NErr, &nfErr): 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: 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) user := ur.Data.(*model.User)
@@ -209,9 +209,9 @@ func (a *App) DoPostActionWithCookie(c *request.Context, postID, actionId, userI
var nfErr *store.ErrNotFound var nfErr *store.ErrNotFound
switch { switch {
case errors.As(tr.NErr, &nfErr): 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: 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 return "", appErr
} }
var resp *http.Response
if strings.HasPrefix(upstreamURL, "/warn_metrics/") { if strings.HasPrefix(upstreamURL, "/warn_metrics/") {
appErr = a.doLocalWarnMetricsRequest(c, upstreamURL, upstreamRequest) appErr = a.doLocalWarnMetricsRequest(c, upstreamURL, upstreamRequest)
if appErr != nil { if appErr != nil {
@@ -242,25 +241,26 @@ func (a *App) DoPostActionWithCookie(c *request.Context, postID, actionId, userI
} }
return "", nil return "", nil
} }
requestJSON, jsonErr := json.Marshal(upstreamRequest)
if jsonErr != nil { requestJSON, err := json.Marshal(upstreamRequest)
return "", model.NewAppError("DoPostActionWithCookie", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) 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 { if appErr != nil {
return "", appErr return "", appErr
} }
defer resp.Body.Close() defer resp.Body.Close()
var response model.PostActionIntegrationResponse var response model.PostActionIntegrationResponse
respBytes, err := ioutil.ReadAll(resp.Body) respBytes, err := io.ReadAll(resp.Body)
if err != nil { 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 len(respBytes) > 0 {
if err = json.Unmarshal(respBytes, &response); err != nil { 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)
} }
} }
@@ -435,7 +435,7 @@ func (ch *Channels) doPluginRequest(c *request.Context, method, rawURL string, v
ProtoMajor: 1, ProtoMajor: 1,
ProtoMinor: 1, ProtoMinor: 1,
Header: w.headers, Header: w.headers,
Body: ioutil.NopCloser(bytes.NewReader(w.data)), Body: io.NopCloser(bytes.NewReader(w.data)),
} }
if resp.StatusCode == 0 { if resp.StatusCode == 0 {
resp.StatusCode = http.StatusOK resp.StatusCode = http.StatusOK
@@ -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 { func (a *App) OpenInteractiveDialog(request model.OpenDialogRequest) *model.AppError {
clientTriggerId, userID, err := request.DecodeAndVerifyTriggerId(a.AsymmetricSigningKey()) clientTriggerId, userID, appErr := request.DecodeAndVerifyTriggerId(a.AsymmetricSigningKey())
if err != nil { if appErr != nil {
return err return appErr
} }
request.TriggerId = clientTriggerId 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 := model.NewWebSocketEvent(model.WebsocketEventOpenDialog, "", "", userID, nil)
message.Add("dialog", string(jsonRequest)) message.Add("dialog", string(jsonRequest))
@@ -606,23 +609,19 @@ func (a *App) SubmitInteractiveDialog(c *request.Context, request model.SubmitDi
request.URL = "" request.URL = ""
request.Type = "dialog_submission" request.Type = "dialog_submission"
b, jsonErr := json.Marshal(request) b, err := 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)
if err != nil { 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() defer resp.Body.Close()
var response model.SubmitDialogResponse var response model.SubmitDialogResponse
if err := json.NewDecoder(resp.Body).Decode(&response); err != nil { json.NewDecoder(resp.Body).Decode(&response) // Don't fail, an empty response is acceptable
// Don't fail, an empty response is acceptable
return &response, nil
}
return &response, nil return &response, nil
} }

Просмотреть файл

@@ -6,7 +6,7 @@ package app
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil" "io"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"net/url" "net/url"
@@ -1079,47 +1079,47 @@ func TestDoPluginRequest(t *testing.T) {
resp, err := th.App.doPluginRequest(th.Context, "GET", "/plugins/myplugin", nil, nil) resp, err := th.App.doPluginRequest(th.Context, "GET", "/plugins/myplugin", nil, nil)
assert.Nil(t, err) assert.Nil(t, err)
require.NotNil(t, resp) 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)) 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) resp, err = th.App.doPluginRequest(th.Context, "GET", "/plugins/myplugin?abc=xyz", nil, nil)
assert.Nil(t, err) assert.Nil(t, err)
require.NotNil(t, resp) 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)) assert.Equal(t, "param multiple should have 3 values", string(body))
resp, err = th.App.doPluginRequest(th.Context, "GET", "/plugins/myplugin", resp, err = th.App.doPluginRequest(th.Context, "GET", "/plugins/myplugin",
url.Values{"abc": []string{"xyz"}, "multiple": []string{"1 first", "2 second", "3 third"}}, nil) url.Values{"abc": []string{"xyz"}, "multiple": []string{"1 first", "2 second", "3 third"}}, nil)
assert.Nil(t, err) assert.Nil(t, err)
require.NotNil(t, resp) require.NotNil(t, resp)
body, _ = ioutil.ReadAll(resp.Body) body, _ = io.ReadAll(resp.Body)
assert.Equal(t, "OK", string(body)) assert.Equal(t, "OK", string(body))
resp, err = th.App.doPluginRequest(th.Context, "GET", "/plugins/myplugin?abc=xyz&multiple=1%20first", resp, err = th.App.doPluginRequest(th.Context, "GET", "/plugins/myplugin?abc=xyz&multiple=1%20first",
url.Values{"multiple": []string{"2 second", "3 third"}}, nil) url.Values{"multiple": []string{"2 second", "3 third"}}, nil)
assert.Nil(t, err) assert.Nil(t, err)
require.NotNil(t, resp) require.NotNil(t, resp)
body, _ = ioutil.ReadAll(resp.Body) body, _ = io.ReadAll(resp.Body)
assert.Equal(t, "OK", string(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", 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) url.Values{"multiple": []string{"2 second"}}, nil)
assert.Nil(t, err) assert.Nil(t, err)
require.NotNil(t, resp) require.NotNil(t, resp)
body, _ = ioutil.ReadAll(resp.Body) body, _ = io.ReadAll(resp.Body)
assert.Equal(t, "OK", string(body)) assert.Equal(t, "OK", string(body))
resp, err = th.App.doPluginRequest(th.Context, "GET", "/plugins/myplugin?multiple=1%20first&multiple=3%20third", 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) url.Values{"multiple": []string{"2 second"}, "abc": []string{"xyz"}}, nil)
assert.Nil(t, err) assert.Nil(t, err)
require.NotNil(t, resp) require.NotNil(t, resp)
body, _ = ioutil.ReadAll(resp.Body) body, _ = io.ReadAll(resp.Body)
assert.Equal(t, "OK", string(body)) assert.Equal(t, "OK", string(body))
resp, err = th.App.doPluginRequest(th.Context, "GET", "/plugins/myplugin?multiple=1%20first&multiple=3%20third", 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) url.Values{"multiple": []string{"4 fourth"}, "abc": []string{"xyz"}}, nil)
assert.Nil(t, err) assert.Nil(t, err)
require.NotNil(t, resp) require.NotNil(t, resp)
body, _ = ioutil.ReadAll(resp.Body) body, _ = io.ReadAll(resp.Body)
assert.Equal(t, "param multiple not correct", string(body)) assert.Equal(t, "param multiple not correct", string(body))
} }

Просмотреть файл

@@ -10,7 +10,7 @@ import (
"go/ast" "go/ast"
"go/parser" "go/parser"
"go/token" "go/token"
"io/ioutil" "io"
"log" "log"
"os" "os"
"path" "path"
@@ -58,7 +58,7 @@ func main() {
log.Fatal(err) log.Fatal(err)
} }
err = ioutil.WriteFile(outputFile, formattedCode, 0644) err = os.WriteFile(outputFile, formattedCode, 0644)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
@@ -162,7 +162,7 @@ func extractStoreMetadata() (*storeMetadata, error) {
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to open %s file: %w", inputFile, err) 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 { if err != nil {
return nil, err return nil, err
} }

Просмотреть файл

@@ -4,7 +4,7 @@
package app package app
import ( import (
"io/ioutil" "io"
"mime/multipart" "mime/multipart"
"net/http" "net/http"
@@ -186,12 +186,12 @@ func (a *App) writeLdapFile(filename string, fileData *multipart.FileHeader) *mo
} }
defer file.Close() defer file.Close()
data, err := ioutil.ReadAll(file) data, err := io.ReadAll(file)
if err != nil { if err != nil {
return model.NewAppError("AddLdapCertificate", "api.admin.add_certificate.saving.app_error", nil, err.Error(), http.StatusInternalServerError) 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 { if err != nil {
return model.NewAppError("AddLdapCertificate", "api.admin.add_certificate.saving.app_error", nil, err.Error(), http.StatusInternalServerError) 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 { 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 model.NewAppError("RemoveLdapFile", "api.admin.remove_certificate.delete.app_error", map[string]any{"Filename": filename}, err.Error(), http.StatusInternalServerError)
} }
return nil return nil

Просмотреть файл

@@ -48,7 +48,7 @@ func (w *licenseWrapper) GetLicense() *model.License {
} }
func (w *licenseWrapper) RequestTrialLicense(requesterID string, users int, termsAccepted bool, receiveEmailsAccepted bool) *model.AppError { 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) 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(), ServerID: w.srv.TelemetryId(),
Name: requester.GetDisplayName(model.ShowFullName), Name: requester.GetDisplayName(model.ShowFullName),
Email: requester.Email, Email: requester.Email,
SiteName: *w.srv.Config().TeamSettings.SiteName, SiteName: *w.srv.platform.Config().TeamSettings.SiteName,
SiteURL: *w.srv.Config().ServiceSettings.SiteURL, SiteURL: *w.srv.platform.Config().ServiceSettings.SiteURL,
Users: users, Users: users,
TermsAccepted: termsAccepted, TermsAccepted: termsAccepted,
ReceiveEmailsAccepted: receiveEmailsAccepted, ReceiveEmailsAccepted: receiveEmailsAccepted,
@@ -93,6 +93,11 @@ type JWTClaims struct {
jwt.StandardClaims jwt.StandardClaims
} }
func (s *Server) License() *model.License {
license, _ := s.licenseValue.Load().(*model.License)
return license
}
func (s *Server) LoadLicense() { func (s *Server) LoadLicense() {
// ENV var overrides all other sources of license. // ENV var overrides all other sources of license.
licenseStr := os.Getenv(LicenseEnv) licenseStr := os.Getenv(LicenseEnv)
@@ -131,7 +136,7 @@ func (s *Server) LoadLicense() {
if !model.IsValidId(licenseId) { if !model.IsValidId(licenseId) {
// Lets attempt to load the file from disk since it was missing from the DB // 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 license != nil {
if _, err := s.SaveLicense(licenseBytes); err != 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) 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) { if err := s.Jobs.StopWorkers(); err != nil && !errors.Is(err, jobs.ErrWorkersNotRunning) {
mlog.Warn("Stopping job server workers failed", mlog.Err(err)) 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) { if err := s.Jobs.StopSchedulers(); err != nil && !errors.Is(err, jobs.ErrSchedulersNotRunning) {
mlog.Error("Stopping job server schedulers failed", mlog.Err(err)) 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 // 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 // doesn't start until the server is restarted, which prevents the 'run job now' buttons in system console from
// functioning as expected // 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 { if err := s.Jobs.StartWorkers(); err != nil {
mlog.Error("Starting job server workers failed", mlog.Err(err)) 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) { if err := s.Jobs.StartSchedulers(); err != nil && !errors.Is(err, jobs.ErrSchedulersRunning) {
mlog.Error("Starting job server schedulers failed", mlog.Err(err)) 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) return nil, model.NewAppError("addLicense", "api.license.add_license.save_active.app_error", nil, "", http.StatusInternalServerError)
} }
s.ReloadConfig() s.platform.ReloadConfig()
s.InvalidateAllCaches() s.InvalidateAllCaches()
return &license, nil return &license, nil
@@ -256,12 +261,20 @@ func (s *Server) SetLicense(license *model.License) bool {
license.Features.SetDefaults() license.Features.SetDefaults()
s.licenseValue.Store(license) s.licenseValue.Store(license)
if s.platform != nil {
s.platform.SetLicense(license)
}
s.clientLicenseValue.Store(utils.GetClientLicense(license)) s.clientLicenseValue.Store(utils.GetClientLicense(license))
return true return true
} }
s.licenseValue.Store((*model.License)(nil)) s.licenseValue.Store((*model.License)(nil))
s.clientLicenseValue.Store(map[string]string(nil)) s.clientLicenseValue.Store(map[string]string(nil))
if s.platform != nil {
s.platform.SetLicense((*model.License)(nil))
}
return false return false
} }
@@ -307,7 +320,7 @@ func (s *Server) RemoveLicense() *model.AppError {
} }
s.SetLicense(nil) s.SetLicense(nil)
s.ReloadConfig() s.platform.ReloadConfig()
s.InvalidateAllCaches() s.InvalidateAllCaches()
return nil return nil
@@ -329,14 +342,14 @@ func (s *Server) GetSanitizedClientLicense() map[string]string {
// RequestTrialLicense request a trial license from the mattermost official license server // RequestTrialLicense request a trial license from the mattermost official license server
func (s *Server) RequestTrialLicense(trialRequest *model.TrialLicenseRequest) *model.AppError { func (s *Server) RequestTrialLicense(trialRequest *model.TrialLicenseRequest) *model.AppError {
trialRequestJSON, jsonErr := json.Marshal(trialRequest) trialRequestJSON, err := json.Marshal(trialRequest)
if jsonErr != nil { if err != nil {
return model.NewAppError("RequestTrialLicense", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) return model.NewAppError("RequestTrialLicense", "api.unmarshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
} }
resp, err := http.Post(RequestTrialURL, "application/json", bytes.NewBuffer(trialRequestJSON)) resp, err := http.Post(RequestTrialURL, "application/json", bytes.NewBuffer(trialRequestJSON))
if err != nil { 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() defer resp.Body.Close()
@@ -350,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) 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 { if _, ok := licenseResponse["license"]; !ok {
return model.NewAppError("RequestTrialLicense", "api.license.request_trial_license.app_error", nil, licenseResponse["message"], http.StatusBadRequest) return model.NewAppError("RequestTrialLicense", "api.license.request_trial_license.app_error", nil, licenseResponse["message"], http.StatusBadRequest)
@@ -360,7 +377,7 @@ func (s *Server) RequestTrialLicense(trialRequest *model.TrialLicenseRequest) *m
return err return err
} }
s.ReloadConfig() s.platform.ReloadConfig()
s.InvalidateAllCaches() s.InvalidateAllCaches()
return nil return nil

Просмотреть файл

@@ -69,9 +69,9 @@ func (s *Server) doAdvancedPermissionsMigration() {
return return
} }
config := s.Config() config := s.platform.Config()
*config.ServiceSettings.PostEditTimeLimit = -1 *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)) mlog.Error("Failed to update config in Advanced Permissions Phase 1 Migration.", mlog.Err(err))
} }
@@ -327,7 +327,7 @@ func (s *Server) doContentExtractionConfigDefaultTrueMigration() {
return return
} }
s.UpdateConfig(func(config *model.Config) { s.platform.UpdateConfig(func(config *model.Config) {
config.FileSettings.ExtractContent = model.NewBool(true) config.FileSettings.ExtractContent = model.NewBool(true)
}) })
@@ -474,7 +474,7 @@ const existingInstallationPostsThreshold = 10
func (s *Server) doFirstAdminSetupCompleteMigration() { func (s *Server) doFirstAdminSetupCompleteMigration() {
// Don't run the migration until the flag is turned on. // Don't run the migration until the flag is turned on.
if !s.Config().FeatureFlags.UseCaseOnboarding { if !s.platform.Config().FeatureFlags.UseCaseOnboarding {
return return
} }

Просмотреть файл

@@ -6,14 +6,14 @@ package app
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"errors"
"fmt"
"io" "io"
"net/http" "net/http"
"runtime" "runtime"
"strings" "strings"
"sync" "sync"
"github.com/pkg/errors"
"github.com/mattermost/mattermost-server/v6/app/request" "github.com/mattermost/mattermost-server/v6/app/request"
"github.com/mattermost/mattermost-server/v6/model" "github.com/mattermost/mattermost-server/v6/model"
"github.com/mattermost/mattermost-server/v6/shared/i18n" "github.com/mattermost/mattermost-server/v6/shared/i18n"
@@ -290,7 +290,7 @@ func (a *App) UpdateMobileAppBadge(userID string) {
} }
func (s *Server) createPushNotificationsHub(c request.CTX) { func (s *Server) createPushNotificationsHub(c request.CTX) {
buffer := *s.Config().EmailSettings.PushNotificationBuffer buffer := *s.platform.Config().EmailSettings.PushNotificationBuffer
hub := PushNotificationsHub{ hub := PushNotificationsHub{
notificationsChan: make(chan PushNotification, buffer), notificationsChan: make(chan PushNotification, buffer),
app: New(ServerConnector(s.Channels())), app: New(ServerConnector(s.Channels())),
@@ -382,9 +382,9 @@ func (s *Server) StopPushNotificationsHubWorkers() {
} }
func (a *App) rawSendToPushProxy(msg *model.PushNotification) (model.PushResponse, error) { func (a *App) rawSendToPushProxy(msg *model.PushNotification) (model.PushResponse, error) {
msgJSON, jsonErr := json.Marshal(msg) msgJSON, err := json.Marshal(msg)
if jsonErr != nil { if err != nil {
return nil, errors.Wrap(jsonErr, "failed to encode to JSON") return nil, fmt.Errorf("failed to encode to JSON: %w", err)
} }
url := strings.TrimRight(*a.Config().EmailSettings.PushNotificationServer, "/") + model.APIURLSuffixV1 + "/send_push" 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() defer resp.Body.Close()
var pushResponse model.PushResponse var pushResponse model.PushResponse
if jsonErr := json.NewDecoder(resp.Body).Decode(&pushResponse); jsonErr != nil { if err := json.NewDecoder(resp.Body).Decode(&pushResponse); err != nil {
return nil, errors.Wrap(jsonErr, "failed to decode from JSON") return nil, fmt.Errorf("failed to decode from JSON: %w", err)
} }
return pushResponse, nil return pushResponse, nil
@@ -427,7 +427,7 @@ func (a *App) sendToPushProxy(msg *model.PushNotification, session *model.Sessio
case model.PushStatusRemove: case model.PushStatusRemove:
a.AttachDeviceId(session.Id, "", session.ExpiresAt) a.AttachDeviceId(session.Id, "", session.ExpiresAt)
a.ClearSessionCacheForUser(session.UserId) a.ClearSessionCacheForUser(session.UserId)
return errors.New("Device was reported as removed") return errors.New("device was reported as removed")
case model.PushStatusFail: case model.PushStatusFail:
return errors.New(pushResponse[model.PushStatusErrorMsg]) return errors.New(pushResponse[model.PushStatusErrorMsg])
} }
@@ -447,9 +447,9 @@ func (a *App) SendAckToPushProxy(ack *model.PushNotificationAck) error {
mlog.String("status", model.PushReceived), mlog.String("status", model.PushReceived),
) )
ackJSON, jsonErr := json.Marshal(ack) ackJSON, err := json.Marshal(ack)
if jsonErr != nil { if err != nil {
return errors.Wrap(jsonErr, "failed to encode to JSON") return fmt.Errorf("failed to encode to JSON: %w", err)
} }
request, err := http.NewRequest( 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", strings.TrimRight(*a.Config().EmailSettings.PushNotificationServer, "/")+model.APIURLSuffixV1+"/ack",
bytes.NewReader(ackJSON), bytes.NewReader(ackJSON),
) )
if err != nil { if err != nil {
return err return err
} }
@@ -467,19 +466,16 @@ func (a *App) SendAckToPushProxy(ack *model.PushNotificationAck) error {
return err return err
} }
defer resp.Body.Close() defer resp.Body.Close()
// Reading the body to completion. // Reading the body to completion.
_, err = io.Copy(io.Discard, resp.Body) _, err = io.Copy(io.Discard, resp.Body)
if err != nil { return err
return err
}
return nil
} }
func (a *App) getMobileAppSessions(userID string) ([]*model.Session, *model.AppError) { func (a *App) getMobileAppSessions(userID string) ([]*model.Session, *model.AppError) {
sessions, err := a.Srv().Store.Session().GetSessionsWithActiveDeviceIds(userID) sessions, err := a.Srv().Store.Session().GetSessionsWithActiveDeviceIds(userID)
if err != nil { 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 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) unreadCount, err := a.Srv().Store.User().GetUnreadCount(user.Id)
if err != nil { 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) msg.Badge = int(unreadCount)

Просмотреть файл

@@ -17,6 +17,7 @@ import (
"github.com/stretchr/testify/mock" "github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require" "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/config"
"github.com/mattermost/mattermost-server/v6/model" "github.com/mattermost/mattermost-server/v6/model"
fmocks "github.com/mattermost/mattermost-server/v6/shared/filestore/mocks" fmocks "github.com/mattermost/mattermost-server/v6/shared/filestore/mocks"
@@ -1443,9 +1444,13 @@ func TestPushNotificationRace(t *testing.T) {
Router: mux.NewRouter(), Router: mux.NewRouter(),
filestore: &fmocks.FileBackend{}, 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{ serviceMap := map[ServiceKey]any{
ConfigKey: s.configStore, ConfigKey: s.platform,
LicenseKey: &licenseWrapper{s}, LicenseKey: &licenseWrapper{s},
FilestoreKey: s.filestore, FilestoreKey: s.filestore,
} }

Просмотреть файл

@@ -11,7 +11,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
"strconv" "strconv"
@@ -853,7 +852,7 @@ func (a *App) AuthorizeOAuthUser(w http.ResponseWriter, r *http.Request, service
var ar *model.AccessResponse var ar *model.AccessResponse
err = json.NewDecoder(tee).Decode(&ar) err = json.NewDecoder(tee).Decode(&ar)
if err != nil || resp.StatusCode != http.StatusOK { 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 { if strings.ToLower(ar.TokenType) != model.AccessTokenType {
@@ -891,7 +890,7 @@ func (a *App) AuthorizeOAuthUser(w http.ResponseWriter, r *http.Request, service
defer resp.Body.Close() defer resp.Body.Close()
// Ignore the error below because the resulting string will just be the empty string if bodyBytes is nil // 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) bodyString := string(bodyBytes)
mlog.Error("Error getting OAuth user", mlog.Int("response", resp.StatusCode), mlog.String("body_string", bodyString)) mlog.Error("Error getting OAuth user", mlog.Int("response", resp.StatusCode), mlog.String("body_string", bodyString))

Просмотреть файл

@@ -7,7 +7,7 @@ import (
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"errors" "errors"
"io/ioutil" "io"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"testing" "testing"
@@ -517,7 +517,7 @@ func TestAuthorizeOAuthUser(t *testing.T) {
body, receivedTeamId, receivedStateProps, _, err := th.App.AuthorizeOAuthUser(&recorder, request, model.ServiceGitlab, "", state, "") body, receivedTeamId, receivedStateProps, _, err := th.App.AuthorizeOAuthUser(&recorder, request, model.ServiceGitlab, "", state, "")
require.NotNil(t, body) require.NotNil(t, body)
bodyBytes, bodyErr := ioutil.ReadAll(body) bodyBytes, bodyErr := io.ReadAll(body)
require.NoError(t, bodyErr) require.NoError(t, bodyErr)
assert.Equal(t, userData, string(bodyBytes)) assert.Equal(t, userData, string(bodyBytes))

Просмотреть файл

@@ -6,6 +6,7 @@ package app
import ( import (
"github.com/pkg/errors" "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/config"
"github.com/mattermost/mattermost-server/v6/einterfaces" "github.com/mattermost/mattermost-server/v6/einterfaces"
"github.com/mattermost/mattermost-server/v6/model" "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") 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 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. // ConfigStore applies the given config store, typically to replace the traditional sources with a memory store for testing.
func ConfigStore(configStore *config.Store) Option { func ConfigStore(configStore *config.Store) Option {
return func(s *Server) error { 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 return nil
} }

12
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
}

Просмотреть файл

@@ -5,9 +5,14 @@ package platform
import ( import (
"errors" "errors"
"fmt"
"net/http"
"reflect"
"github.com/mattermost/mattermost-server/v6/config" "github.com/mattermost/mattermost-server/v6/config"
"github.com/mattermost/mattermost-server/v6/einterfaces" "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" "github.com/mattermost/mattermost-server/v6/shared/mlog"
) )
@@ -30,7 +35,145 @@ func (c *ServiceConfig) validate() error {
} }
if c.Logger == nil { 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 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)
}

47
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")
}

118
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
}
}

87
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
}

32
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)
}

19
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)
}

Просмотреть файл

@@ -4,6 +4,11 @@
package platform package platform
import ( 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/config"
"github.com/mattermost/mattermost-server/v6/einterfaces" "github.com/mattermost/mattermost-server/v6/einterfaces"
"github.com/mattermost/mattermost-server/v6/shared/mlog" "github.com/mattermost/mattermost-server/v6/shared/mlog"
@@ -19,6 +24,14 @@ type PlatformService struct {
metrics *platformMetrics metrics *platformMetrics
featureFlagSynchronizerMutex sync.Mutex
featureFlagSynchronizer *featureflag.Synchronizer
featureFlagStop chan struct{}
featureFlagStopped chan struct{}
licenseValue atomic.Value
telemetryId string
cluster einterfaces.ClusterInterface cluster einterfaces.ClusterInterface
} }
@@ -49,3 +62,18 @@ func (ps *PlatformService) ShutdownMetrics() error {
return nil 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
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше