[MM-42782] Incoming webhooks change their creator's status (#22050)
Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
f713862041
Коммит
56424a7601
@@ -494,7 +494,7 @@ type AppIface interface {
|
|||||||
CreatePasswordRecoveryToken(userID, email string) (*model.Token, *model.AppError)
|
CreatePasswordRecoveryToken(userID, email string) (*model.Token, *model.AppError)
|
||||||
CreatePost(c request.CTX, post *model.Post, channel *model.Channel, triggerWebhooks, setOnline bool) (savedPost *model.Post, err *model.AppError)
|
CreatePost(c request.CTX, post *model.Post, channel *model.Channel, triggerWebhooks, setOnline bool) (savedPost *model.Post, err *model.AppError)
|
||||||
CreatePostAsUser(c request.CTX, post *model.Post, currentSessionId string, setOnline bool) (*model.Post, *model.AppError)
|
CreatePostAsUser(c request.CTX, post *model.Post, currentSessionId string, setOnline bool) (*model.Post, *model.AppError)
|
||||||
CreatePostMissingChannel(c request.CTX, post *model.Post, triggerWebhooks bool) (*model.Post, *model.AppError)
|
CreatePostMissingChannel(c request.CTX, post *model.Post, triggerWebhooks bool, setOnline bool) (*model.Post, *model.AppError)
|
||||||
CreateRetentionPolicy(policy *model.RetentionPolicyWithTeamAndChannelIDs) (*model.RetentionPolicyWithTeamAndChannelCounts, *model.AppError)
|
CreateRetentionPolicy(policy *model.RetentionPolicyWithTeamAndChannelIDs) (*model.RetentionPolicyWithTeamAndChannelCounts, *model.AppError)
|
||||||
CreateRole(role *model.Role) (*model.Role, *model.AppError)
|
CreateRole(role *model.Role) (*model.Role, *model.AppError)
|
||||||
CreateScheme(scheme *model.Scheme) (*model.Scheme, *model.AppError)
|
CreateScheme(scheme *model.Scheme) (*model.Scheme, *model.AppError)
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ func (a *App) CreateCommandPost(c request.CTX, post *model.Post, teamID string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if response.ResponseType == model.CommandResponseTypeInChannel {
|
if response.ResponseType == model.CommandResponseTypeInChannel {
|
||||||
return a.CreatePostMissingChannel(c, post, true)
|
return a.CreatePostMissingChannel(c, post, true, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.ResponseType == "" || response.ResponseType == model.CommandResponseTypeEphemeral) && (response.Text != "" || response.Attachments != nil) {
|
if (response.ResponseType == "" || response.ResponseType == model.CommandResponseTypeEphemeral) && (response.Text != "" || response.Attachments != nil) {
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ func TestSendNotifications(t *testing.T) {
|
|||||||
Message: "@" + th.BasicUser2.Username,
|
Message: "@" + th.BasicUser2.Username,
|
||||||
Type: model.PostTypeAddToChannel,
|
Type: model.PostTypeAddToChannel,
|
||||||
Props: map[string]any{model.PostPropsAddedUserId: "junk"},
|
Props: map[string]any{model.PostPropsAddedUserId: "junk"},
|
||||||
}, true)
|
}, true, true)
|
||||||
require.Nil(t, appErr)
|
require.Nil(t, appErr)
|
||||||
|
|
||||||
mentions, err := th.App.SendNotifications(th.Context, post1, th.BasicTeam, th.BasicChannel, th.BasicUser, nil, true)
|
mentions, err := th.App.SendNotifications(th.Context, post1, th.BasicTeam, th.BasicChannel, th.BasicUser, nil, true)
|
||||||
@@ -87,7 +87,7 @@ func TestSendNotifications(t *testing.T) {
|
|||||||
UserId: th.BasicUser.Id,
|
UserId: th.BasicUser.Id,
|
||||||
ChannelId: dm.Id,
|
ChannelId: dm.Id,
|
||||||
Message: "dm message",
|
Message: "dm message",
|
||||||
}, true)
|
}, true, true)
|
||||||
require.Nil(t, appErr)
|
require.Nil(t, appErr)
|
||||||
|
|
||||||
mentions, err = th.App.SendNotifications(th.Context, post2, th.BasicTeam, dm, th.BasicUser, nil, true)
|
mentions, err = th.App.SendNotifications(th.Context, post2, th.BasicTeam, dm, th.BasicUser, nil, true)
|
||||||
@@ -103,7 +103,7 @@ func TestSendNotifications(t *testing.T) {
|
|||||||
UserId: th.BasicUser.Id,
|
UserId: th.BasicUser.Id,
|
||||||
ChannelId: dm.Id,
|
ChannelId: dm.Id,
|
||||||
Message: "dm message",
|
Message: "dm message",
|
||||||
}, true)
|
}, true, true)
|
||||||
require.Nil(t, appErr)
|
require.Nil(t, appErr)
|
||||||
|
|
||||||
mentions, err = th.App.SendNotifications(th.Context, post3, th.BasicTeam, dm, th.BasicUser, nil, true)
|
mentions, err = th.App.SendNotifications(th.Context, post3, th.BasicTeam, dm, th.BasicUser, nil, true)
|
||||||
@@ -126,7 +126,7 @@ func TestSendNotifications(t *testing.T) {
|
|||||||
Props: model.StringInterface{"from_webhook": "true", "override_username": "a bot"},
|
Props: model.StringInterface{"from_webhook": "true", "override_username": "a bot"},
|
||||||
}
|
}
|
||||||
|
|
||||||
rootPost, appErr = th.App.CreatePostMissingChannel(th.Context, rootPost, false)
|
rootPost, appErr = th.App.CreatePostMissingChannel(th.Context, rootPost, false, true)
|
||||||
require.Nil(t, appErr)
|
require.Nil(t, appErr)
|
||||||
|
|
||||||
childPost := &model.Post{
|
childPost := &model.Post{
|
||||||
@@ -135,7 +135,7 @@ func TestSendNotifications(t *testing.T) {
|
|||||||
RootId: rootPost.Id,
|
RootId: rootPost.Id,
|
||||||
Message: "a reply",
|
Message: "a reply",
|
||||||
}
|
}
|
||||||
childPost, appErr = th.App.CreatePostMissingChannel(th.Context, childPost, false)
|
childPost, appErr = th.App.CreatePostMissingChannel(th.Context, childPost, false, true)
|
||||||
require.Nil(t, appErr)
|
require.Nil(t, appErr)
|
||||||
|
|
||||||
postList := model.PostList{
|
postList := model.PostList{
|
||||||
@@ -181,7 +181,7 @@ func TestSendNotificationsWithManyUsers(t *testing.T) {
|
|||||||
Message: "@channel",
|
Message: "@channel",
|
||||||
Type: model.PostTypeAddToChannel,
|
Type: model.PostTypeAddToChannel,
|
||||||
Props: map[string]any{model.PostPropsAddedUserId: "junk"},
|
Props: map[string]any{model.PostPropsAddedUserId: "junk"},
|
||||||
}, true)
|
}, true, true)
|
||||||
require.Nil(t, appErr1)
|
require.Nil(t, appErr1)
|
||||||
|
|
||||||
// Each user should have a mention count of exactly 1 in the DB at this point.
|
// Each user should have a mention count of exactly 1 in the DB at this point.
|
||||||
@@ -201,7 +201,7 @@ func TestSendNotificationsWithManyUsers(t *testing.T) {
|
|||||||
Message: "@channel",
|
Message: "@channel",
|
||||||
Type: model.PostTypeAddToChannel,
|
Type: model.PostTypeAddToChannel,
|
||||||
Props: map[string]any{model.PostPropsAddedUserId: "junk"},
|
Props: map[string]any{model.PostPropsAddedUserId: "junk"},
|
||||||
}, true)
|
}, true, true)
|
||||||
require.Nil(t, appErr1)
|
require.Nil(t, appErr1)
|
||||||
|
|
||||||
// Now each user should have a mention count of exactly 2 in the DB.
|
// Now each user should have a mention count of exactly 2 in the DB.
|
||||||
@@ -2794,7 +2794,7 @@ func TestReplyPostNotificationsWithCRT(t *testing.T) {
|
|||||||
Props: model.StringInterface{"from_webhook": "true", "override_username": "a bot"},
|
Props: model.StringInterface{"from_webhook": "true", "override_username": "a bot"},
|
||||||
}
|
}
|
||||||
|
|
||||||
rootPost, appErr := th.App.CreatePostMissingChannel(th.Context, rootPost, false)
|
rootPost, appErr := th.App.CreatePostMissingChannel(th.Context, rootPost, false, true)
|
||||||
require.Nil(t, appErr)
|
require.Nil(t, appErr)
|
||||||
|
|
||||||
childPost := &model.Post{
|
childPost := &model.Post{
|
||||||
@@ -2803,7 +2803,7 @@ func TestReplyPostNotificationsWithCRT(t *testing.T) {
|
|||||||
RootId: rootPost.Id,
|
RootId: rootPost.Id,
|
||||||
Message: "a reply",
|
Message: "a reply",
|
||||||
}
|
}
|
||||||
childPost, appErr = th.App.CreatePostMissingChannel(th.Context, childPost, false)
|
childPost, appErr = th.App.CreatePostMissingChannel(th.Context, childPost, false, true)
|
||||||
require.Nil(t, appErr)
|
require.Nil(t, appErr)
|
||||||
|
|
||||||
postList := model.PostList{
|
postList := model.PostList{
|
||||||
|
|||||||
@@ -2339,7 +2339,7 @@ func (a *OpenTracingAppLayer) CreatePostAsUser(c request.CTX, post *model.Post,
|
|||||||
return resultVar0, resultVar1
|
return resultVar0, resultVar1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *OpenTracingAppLayer) CreatePostMissingChannel(c request.CTX, post *model.Post, triggerWebhooks bool) (*model.Post, *model.AppError) {
|
func (a *OpenTracingAppLayer) CreatePostMissingChannel(c request.CTX, post *model.Post, triggerWebhooks bool, setOnline bool) (*model.Post, *model.AppError) {
|
||||||
origCtx := a.ctx
|
origCtx := a.ctx
|
||||||
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.CreatePostMissingChannel")
|
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.CreatePostMissingChannel")
|
||||||
|
|
||||||
@@ -2351,7 +2351,7 @@ func (a *OpenTracingAppLayer) CreatePostMissingChannel(c request.CTX, post *mode
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
resultVar0, resultVar1 := a.app.CreatePostMissingChannel(c, post, triggerWebhooks)
|
resultVar0, resultVar1 := a.app.CreatePostMissingChannel(c, post, triggerWebhooks, setOnline)
|
||||||
|
|
||||||
if resultVar1 != nil {
|
if resultVar1 != nil {
|
||||||
span.LogFields(spanlog.Error(resultVar1))
|
span.LogFields(spanlog.Error(resultVar1))
|
||||||
|
|||||||
@@ -632,7 +632,7 @@ func (api *PluginAPI) GetGroupsForUser(userID string) ([]*model.Group, *model.Ap
|
|||||||
func (api *PluginAPI) CreatePost(post *model.Post) (*model.Post, *model.AppError) {
|
func (api *PluginAPI) CreatePost(post *model.Post) (*model.Post, *model.AppError) {
|
||||||
post.AddProp("from_plugin", "true")
|
post.AddProp("from_plugin", "true")
|
||||||
|
|
||||||
post, appErr := api.app.CreatePostMissingChannel(api.ctx, post, true)
|
post, appErr := api.app.CreatePostMissingChannel(api.ctx, post, true, true)
|
||||||
if post != nil {
|
if post != nil {
|
||||||
post = post.ForPlugin()
|
post = post.ForPlugin()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ type postServiceWrapper struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *postServiceWrapper) CreatePost(ctx *request.Context, post *model.Post) (*model.Post, *model.AppError) {
|
func (s *postServiceWrapper) CreatePost(ctx *request.Context, post *model.Post) (*model.Post, *model.AppError) {
|
||||||
return s.app.CreatePostMissingChannel(ctx, post, true)
|
return s.app.CreatePostMissingChannel(ctx, post, true, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *postServiceWrapper) GetPostsByIds(postIDs []string) ([]*model.Post, int64, *model.AppError) {
|
func (s *postServiceWrapper) GetPostsByIds(postIDs []string) ([]*model.Post, int64, *model.AppError) {
|
||||||
@@ -115,7 +115,7 @@ func (a *App) CreatePostAsUser(c request.CTX, post *model.Post, currentSessionId
|
|||||||
return rp, nil
|
return rp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) CreatePostMissingChannel(c request.CTX, post *model.Post, triggerWebhooks bool) (*model.Post, *model.AppError) {
|
func (a *App) CreatePostMissingChannel(c request.CTX, post *model.Post, triggerWebhooks bool, setOnline bool) (*model.Post, *model.AppError) {
|
||||||
channel, err := a.Srv().Store().Channel().Get(post.ChannelId, true)
|
channel, err := a.Srv().Store().Channel().Get(post.ChannelId, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
var nfErr *store.ErrNotFound
|
var nfErr *store.ErrNotFound
|
||||||
@@ -127,7 +127,7 @@ func (a *App) CreatePostMissingChannel(c request.CTX, post *model.Post, triggerW
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return a.CreatePost(c, post, channel, triggerWebhooks, true)
|
return a.CreatePost(c, post, channel, triggerWebhooks, setOnline)
|
||||||
}
|
}
|
||||||
|
|
||||||
// deduplicateCreatePost attempts to make posting idempotent within a caching window.
|
// deduplicateCreatePost attempts to make posting idempotent within a caching window.
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ func (cfg *AutoPostCreator) CreateRandomPostNested(c request.CTX, rootId string)
|
|||||||
post.UserId = cfg.UsersToPostFrom[i]
|
post.UserId = cfg.UsersToPostFrom[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rpost, err := cfg.a.CreatePostMissingChannel(c, post, true)
|
rpost, err := cfg.a.CreatePostMissingChannel(c, post, true, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ func (*EchoProvider) DoCommand(a *app.App, c request.CTX, args *model.CommandArg
|
|||||||
|
|
||||||
time.Sleep(time.Duration(delay) * time.Second)
|
time.Sleep(time.Duration(delay) * time.Second)
|
||||||
|
|
||||||
if _, err := a.CreatePostMissingChannel(c, post, true); err != nil {
|
if _, err := a.CreatePostMissingChannel(c, post, true, true); err != nil {
|
||||||
mlog.Error("Unable to create /echo post.", mlog.Err(err))
|
mlog.Error("Unable to create /echo post.", mlog.Err(err))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ func (*groupmsgProvider) DoCommand(a *app.App, c request.CTX, args *model.Comman
|
|||||||
post.Message = parsedMessage
|
post.Message = parsedMessage
|
||||||
post.ChannelId = groupChannel.Id
|
post.ChannelId = groupChannel.Id
|
||||||
post.UserId = args.UserId
|
post.UserId = args.UserId
|
||||||
if _, err := a.CreatePostMissingChannel(c, post, true); err != nil {
|
if _, err := a.CreatePostMissingChannel(c, post, true, true); err != nil {
|
||||||
return &model.CommandResponse{Text: args.T("api.command_groupmsg.fail.app_error"), ResponseType: model.CommandResponseTypeEphemeral}
|
return &model.CommandResponse{Text: args.T("api.command_groupmsg.fail.app_error"), ResponseType: model.CommandResponseTypeEphemeral}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -667,7 +667,7 @@ func (*LoadTestProvider) URLCommand(a *app.App, c request.CTX, args *model.Comma
|
|||||||
post.ChannelId = args.ChannelId
|
post.ChannelId = args.ChannelId
|
||||||
post.UserId = args.UserId
|
post.UserId = args.UserId
|
||||||
|
|
||||||
if _, err := a.CreatePostMissingChannel(c, post, false); err != nil {
|
if _, err := a.CreatePostMissingChannel(c, post, false, true); err != nil {
|
||||||
return &model.CommandResponse{Text: "Unable to create post", ResponseType: model.CommandResponseTypeEphemeral}, err
|
return &model.CommandResponse{Text: "Unable to create post", ResponseType: model.CommandResponseTypeEphemeral}, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -713,7 +713,7 @@ func (*LoadTestProvider) JsonCommand(a *app.App, c request.CTX, args *model.Comm
|
|||||||
post.Message = message
|
post.Message = message
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := a.CreatePostMissingChannel(c, &post, false); err != nil {
|
if _, err := a.CreatePostMissingChannel(c, &post, false, true); err != nil {
|
||||||
return &model.CommandResponse{Text: "Unable to create post", ResponseType: model.CommandResponseTypeEphemeral}, err
|
return &model.CommandResponse{Text: "Unable to create post", ResponseType: model.CommandResponseTypeEphemeral}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ func (*msgProvider) DoCommand(a *app.App, c request.CTX, args *model.CommandArgs
|
|||||||
post.Message = parsedMessage
|
post.Message = parsedMessage
|
||||||
post.ChannelId = targetChannelId
|
post.ChannelId = targetChannelId
|
||||||
post.UserId = args.UserId
|
post.UserId = args.UserId
|
||||||
if _, err = a.CreatePostMissingChannel(c, post, true); err != nil {
|
if _, err = a.CreatePostMissingChannel(c, post, true, true); err != nil {
|
||||||
return &model.CommandResponse{Text: args.T("api.command_msg.fail.app_error"), ResponseType: model.CommandResponseTypeEphemeral}
|
return &model.CommandResponse{Text: args.T("api.command_msg.fail.app_error"), ResponseType: model.CommandResponseTypeEphemeral}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,7 +314,7 @@ func (a *App) CreateWebhookPost(c request.CTX, userID string, channel *model.Cha
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, split := range splits {
|
for _, split := range splits {
|
||||||
if _, err := a.CreatePostMissingChannel(c, split, false); err != nil {
|
if _, err = a.CreatePostMissingChannel(c, split, false, false); err != nil {
|
||||||
return nil, model.NewAppError("CreateWebhookPost", "api.post.create_webhook_post.creating.app_error", nil, "err="+err.Message, http.StatusInternalServerError)
|
return nil, model.NewAppError("CreateWebhookPost", "api.post.create_webhook_post.creating.app_error", nil, "err="+err.Message, http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -18,6 +19,7 @@ import (
|
|||||||
|
|
||||||
"github.com/mattermost/mattermost-server/v6/model"
|
"github.com/mattermost/mattermost-server/v6/model"
|
||||||
"github.com/mattermost/mattermost-server/v6/services/httpservice"
|
"github.com/mattermost/mattermost-server/v6/services/httpservice"
|
||||||
|
"github.com/mattermost/mattermost-server/v6/testlib"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCreateIncomingWebhookForChannel(t *testing.T) {
|
func TestCreateIncomingWebhookForChannel(t *testing.T) {
|
||||||
@@ -361,6 +363,23 @@ Date: Thu Mar 1 19:46:48 2018 +0300
|
|||||||
}, model.PostTypeSlackAttachment, "")
|
}, model.PostTypeSlackAttachment, "")
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
assert.Equal(t, expectedText, post.Message)
|
assert.Equal(t, expectedText, post.Message)
|
||||||
|
|
||||||
|
t.Run("should set webhook creator status to online", func(t *testing.T) {
|
||||||
|
testCluster := &testlib.FakeClusterInterface{}
|
||||||
|
th.Server.Platform().SetCluster(testCluster)
|
||||||
|
defer th.Server.Platform().SetCluster(nil)
|
||||||
|
|
||||||
|
testCluster.ClearMessages()
|
||||||
|
_, appErr := th.App.CreateWebhookPost(th.Context, hook.UserId, th.BasicChannel, "text", "", "", "", model.StringInterface{}, model.PostTypeDefault, "")
|
||||||
|
require.Nil(t, appErr)
|
||||||
|
|
||||||
|
msgs := testCluster.GetMessages()
|
||||||
|
// The first message is ClusterEventInvalidateCacheForChannelByName so we skip it
|
||||||
|
ev, err1 := model.WebSocketEventFromJSON(bytes.NewReader(msgs[1].Data))
|
||||||
|
require.NoError(t, err1)
|
||||||
|
require.Equal(t, model.WebsocketEventPosted, ev.EventType())
|
||||||
|
assert.Equal(t, false, ev.GetData()["set_online"])
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSplitWebhookPost(t *testing.T) {
|
func TestSplitWebhookPost(t *testing.T) {
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user