Merge branch 'master' of github.com:mattermost/mattermost-server into top-dms-clean
Этот коммит содержится в:
11
Makefile
11
Makefile
@@ -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.
|
||||||
|
|||||||
132
api4/cloud.go
132
api4/cloud.go
@@ -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)
|
||||||
|
|||||||
106
api4/config.go
106
api4/config.go
@@ -108,9 +108,10 @@ func configReload(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func updateConfig(c *Context, w http.ResponseWriter, r *http.Request) {
|
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 })
|
||||||
|
|||||||
395
api4/group.go
395
api4/group.go
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
136
api4/insights.go
136
api4/insights.go
@@ -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
|
||||||
|
|||||||
25
api4/job.go
25
api4/job.go
@@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
42
api4/ldap.go
42
api4/ldap.go
@@ -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"))
|
||||||
|
|||||||
13
api4/post.go
13
api4/post.go
@@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
41
api4/role.go
41
api4/role.go
@@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
119
api4/system.go
119
api4/system.go
@@ -195,7 +195,11 @@ func getSystemPing(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testEmail(c *Context, w http.ResponseWriter, r *http.Request) {
|
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)
|
||||||
|
|||||||
300
api4/team.go
300
api4/team.go
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
344
api4/user.go
344
api4/user.go
@@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
11
app/admin.go
11
app/admin.go
@@ -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)))
|
||||||
|
|||||||
116
app/channel.go
116
app/channel.go
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
128
app/config.go
128
app/config.go
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
35
app/emoji.go
35
app/emoji.go
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
61
app/group.go
61
app/group.go
@@ -122,9 +122,9 @@ func (a *App) isUniqueToUsernames(val string) *model.AppError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) CreateGroupWithUserIds(group *model.GroupWithUserIds) (*model.Group, *model.AppError) {
|
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
Обычный файл
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
Обычный файл
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
Обычный файл
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
Обычный файл
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
Обычный файл
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
Обычный файл
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
|
||||||
|
}
|
||||||
|
|||||||
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Ссылка в новой задаче
Block a user