mirror of
https://github.com/mattermost/mattermost.git
synced 2026-02-03 20:40:00 -05:00
* updated go mod and sum files
* fixed var-naming errors in channels/app and channels/api4 dir
* Revert "updated go mod and sum files"
This reverts commit 088dd00a84.
* renamed a cost .
1143 lines
39 KiB
Go
1143 lines
39 KiB
Go
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
package api4
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/url"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/mattermost/mattermost/server/public/model"
|
|
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
|
)
|
|
|
|
func TestCreateCommand(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
client := th.Client
|
|
LocalClient := th.LocalClient
|
|
|
|
enableCommands := *th.App.Config().ServiceSettings.EnableCommands
|
|
defer func() {
|
|
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableCommands = &enableCommands })
|
|
}()
|
|
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableCommands = true })
|
|
|
|
newCmd := &model.Command{
|
|
CreatorId: th.BasicUser.Id,
|
|
TeamId: th.BasicTeam.Id,
|
|
URL: "http://nowhere.com",
|
|
Method: model.CommandMethodPost,
|
|
Trigger: "trigger"}
|
|
|
|
_, resp, err := client.CreateCommand(context.Background(), newCmd)
|
|
require.Error(t, err)
|
|
CheckForbiddenStatus(t, resp)
|
|
|
|
createdCmd, resp, err := th.SystemAdminClient.CreateCommand(context.Background(), newCmd)
|
|
require.NoError(t, err)
|
|
CheckCreatedStatus(t, resp)
|
|
require.Equal(t, th.SystemAdminUser.Id, createdCmd.CreatorId, "user ids didn't match")
|
|
require.Equal(t, th.BasicTeam.Id, createdCmd.TeamId, "team ids didn't match")
|
|
|
|
_, resp, err = th.SystemAdminClient.CreateCommand(context.Background(), newCmd)
|
|
require.Error(t, err)
|
|
CheckBadRequestStatus(t, resp)
|
|
CheckErrorID(t, err, "api.command.duplicate_trigger.app_error")
|
|
|
|
newCmd.Trigger = "Local"
|
|
localCreatedCmd, resp, err := LocalClient.CreateCommand(context.Background(), newCmd)
|
|
require.NoError(t, err)
|
|
CheckCreatedStatus(t, resp)
|
|
require.Equal(t, th.BasicUser.Id, localCreatedCmd.CreatorId, "local client: user ids didn't match")
|
|
require.Equal(t, th.BasicTeam.Id, localCreatedCmd.TeamId, "local client: team ids didn't match")
|
|
|
|
newCmd.Method = "Wrong"
|
|
newCmd.Trigger = "testcommand"
|
|
_, resp, err = th.SystemAdminClient.CreateCommand(context.Background(), newCmd)
|
|
require.Error(t, err)
|
|
CheckBadRequestStatus(t, resp)
|
|
CheckErrorID(t, err, "model.command.is_valid.method.app_error")
|
|
|
|
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableCommands = false })
|
|
newCmd.Method = "P"
|
|
newCmd.Trigger = "testcommand"
|
|
_, resp, err = th.SystemAdminClient.CreateCommand(context.Background(), newCmd)
|
|
require.Error(t, err)
|
|
CheckNotImplementedStatus(t, resp)
|
|
CheckErrorID(t, err, "api.command.disabled.app_error")
|
|
|
|
// Confirm that local clients can't override disable command setting
|
|
newCmd.Trigger = "LocalOverride"
|
|
_, _, err = LocalClient.CreateCommand(context.Background(), newCmd)
|
|
CheckErrorID(t, err, "api.command.disabled.app_error")
|
|
}
|
|
|
|
func TestUpdateCommand(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
user := th.SystemAdminUser
|
|
team := th.BasicTeam
|
|
|
|
enableCommands := *th.App.Config().ServiceSettings.EnableCommands
|
|
defer func() {
|
|
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableCommands = &enableCommands })
|
|
}()
|
|
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableCommands = true })
|
|
|
|
cmd1 := &model.Command{
|
|
CreatorId: user.Id,
|
|
TeamId: team.Id,
|
|
URL: "http://nowhere.com",
|
|
Method: model.CommandMethodPost,
|
|
Trigger: "trigger1",
|
|
}
|
|
|
|
cmd1, _ = th.App.CreateCommand(cmd1)
|
|
|
|
cmd2 := &model.Command{
|
|
CreatorId: GenerateTestID(),
|
|
TeamId: team.Id,
|
|
URL: "http://nowhere.com/change",
|
|
Method: model.CommandMethodGet,
|
|
Trigger: "trigger2",
|
|
Id: cmd1.Id,
|
|
Token: "tokenchange",
|
|
}
|
|
|
|
th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
|
|
rcmd, _, err := client.UpdateCommand(context.Background(), cmd2)
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, cmd2.Trigger, rcmd.Trigger, "Trigger should have updated")
|
|
|
|
require.Equal(t, cmd2.Method, rcmd.Method, "Method should have updated")
|
|
|
|
require.Equal(t, cmd2.URL, rcmd.URL, "URL should have updated")
|
|
|
|
require.Equal(t, cmd1.CreatorId, rcmd.CreatorId, "CreatorId should have not updated")
|
|
|
|
require.Equal(t, cmd1.Token, rcmd.Token, "Token should have not updated")
|
|
|
|
cmd2.Id = GenerateTestID()
|
|
|
|
rcmd, resp, err := client.UpdateCommand(context.Background(), cmd2)
|
|
require.Error(t, err)
|
|
CheckNotFoundStatus(t, resp)
|
|
|
|
require.Nil(t, rcmd, "should be empty")
|
|
|
|
cmd2.Id = "junk"
|
|
|
|
_, resp, err = client.UpdateCommand(context.Background(), cmd2)
|
|
require.Error(t, err)
|
|
CheckBadRequestStatus(t, resp)
|
|
|
|
cmd2.Id = cmd1.Id
|
|
cmd2.TeamId = GenerateTestID()
|
|
|
|
_, resp, err = client.UpdateCommand(context.Background(), cmd2)
|
|
require.Error(t, err)
|
|
CheckBadRequestStatus(t, resp)
|
|
|
|
cmd2.TeamId = team.Id
|
|
|
|
_, resp, err = th.Client.UpdateCommand(context.Background(), cmd2)
|
|
require.Error(t, err)
|
|
CheckNotFoundStatus(t, resp)
|
|
})
|
|
th.SystemAdminClient.Logout(context.Background())
|
|
_, resp, err := th.SystemAdminClient.UpdateCommand(context.Background(), cmd2)
|
|
require.Error(t, err)
|
|
CheckUnauthorizedStatus(t, resp)
|
|
}
|
|
|
|
func TestMoveCommand(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
user := th.SystemAdminUser
|
|
team := th.BasicTeam
|
|
newTeam := th.CreateTeam()
|
|
|
|
enableCommands := *th.App.Config().ServiceSettings.EnableCommands
|
|
defer func() {
|
|
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableCommands = &enableCommands })
|
|
}()
|
|
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableCommands = true })
|
|
|
|
cmd1 := &model.Command{
|
|
CreatorId: user.Id,
|
|
TeamId: team.Id,
|
|
URL: "http://nowhere.com",
|
|
Method: model.CommandMethodPost,
|
|
Trigger: "trigger1",
|
|
}
|
|
|
|
rcmd1, _ := th.App.CreateCommand(cmd1)
|
|
th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
|
|
_, err := client.MoveCommand(context.Background(), newTeam.Id, rcmd1.Id)
|
|
require.NoError(t, err)
|
|
|
|
rcmd1, _ = th.App.GetCommand(rcmd1.Id)
|
|
require.NotNil(t, rcmd1)
|
|
require.Equal(t, newTeam.Id, rcmd1.TeamId)
|
|
|
|
resp, err := client.MoveCommand(context.Background(), newTeam.Id, "bogus")
|
|
require.Error(t, err)
|
|
CheckBadRequestStatus(t, resp)
|
|
|
|
resp, err = client.MoveCommand(context.Background(), GenerateTestID(), rcmd1.Id)
|
|
require.Error(t, err)
|
|
CheckNotFoundStatus(t, resp)
|
|
})
|
|
cmd2 := &model.Command{
|
|
CreatorId: user.Id,
|
|
TeamId: team.Id,
|
|
URL: "http://nowhere.com",
|
|
Method: model.CommandMethodPost,
|
|
Trigger: "trigger2",
|
|
}
|
|
|
|
rcmd2, _ := th.App.CreateCommand(cmd2)
|
|
|
|
resp, err := th.Client.MoveCommand(context.Background(), newTeam.Id, rcmd2.Id)
|
|
require.Error(t, err)
|
|
CheckNotFoundStatus(t, resp)
|
|
|
|
th.SystemAdminClient.Logout(context.Background())
|
|
resp, err = th.SystemAdminClient.MoveCommand(context.Background(), newTeam.Id, rcmd2.Id)
|
|
require.Error(t, err)
|
|
CheckUnauthorizedStatus(t, resp)
|
|
}
|
|
|
|
func TestDeleteCommand(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
user := th.SystemAdminUser
|
|
team := th.BasicTeam
|
|
|
|
enableCommands := *th.App.Config().ServiceSettings.EnableCommands
|
|
defer func() {
|
|
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableCommands = &enableCommands })
|
|
}()
|
|
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableCommands = true })
|
|
|
|
cmd1 := &model.Command{
|
|
CreatorId: user.Id,
|
|
TeamId: team.Id,
|
|
URL: "http://nowhere.com",
|
|
Method: model.CommandMethodPost,
|
|
Trigger: "trigger1",
|
|
}
|
|
|
|
th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
|
|
cmd1.Id = ""
|
|
rcmd1, appErr := th.App.CreateCommand(cmd1)
|
|
require.Nil(t, appErr)
|
|
_, err := client.DeleteCommand(context.Background(), rcmd1.Id)
|
|
require.NoError(t, err)
|
|
|
|
rcmd1, _ = th.App.GetCommand(rcmd1.Id)
|
|
require.Nil(t, rcmd1)
|
|
|
|
resp, err := client.DeleteCommand(context.Background(), "junk")
|
|
require.Error(t, err)
|
|
CheckBadRequestStatus(t, resp)
|
|
|
|
resp, err = client.DeleteCommand(context.Background(), GenerateTestID())
|
|
require.Error(t, err)
|
|
CheckNotFoundStatus(t, resp)
|
|
})
|
|
cmd2 := &model.Command{
|
|
CreatorId: user.Id,
|
|
TeamId: team.Id,
|
|
URL: "http://nowhere.com",
|
|
Method: model.CommandMethodPost,
|
|
Trigger: "trigger2",
|
|
}
|
|
|
|
rcmd2, _ := th.App.CreateCommand(cmd2)
|
|
|
|
resp, err := th.Client.DeleteCommand(context.Background(), rcmd2.Id)
|
|
require.Error(t, err)
|
|
CheckNotFoundStatus(t, resp)
|
|
|
|
th.SystemAdminClient.Logout(context.Background())
|
|
resp, err = th.SystemAdminClient.DeleteCommand(context.Background(), rcmd2.Id)
|
|
require.Error(t, err)
|
|
CheckUnauthorizedStatus(t, resp)
|
|
}
|
|
|
|
func TestListCommands(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
client := th.Client
|
|
|
|
enableCommands := *th.App.Config().ServiceSettings.EnableCommands
|
|
defer func() {
|
|
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableCommands = &enableCommands })
|
|
}()
|
|
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableCommands = true })
|
|
|
|
newCmd := &model.Command{
|
|
CreatorId: th.BasicUser.Id,
|
|
TeamId: th.BasicTeam.Id,
|
|
URL: "http://nowhere.com",
|
|
Method: model.CommandMethodPost,
|
|
Trigger: "custom_command"}
|
|
|
|
_, _, err := th.SystemAdminClient.CreateCommand(context.Background(), newCmd)
|
|
require.NoError(t, err)
|
|
|
|
th.TestForSystemAdminAndLocal(t, func(t *testing.T, c *model.Client4) {
|
|
listCommands, _, err := c.ListCommands(context.Background(), th.BasicTeam.Id, false)
|
|
require.NoError(t, err)
|
|
|
|
foundEcho := false
|
|
foundCustom := false
|
|
for _, command := range listCommands {
|
|
if command.Trigger == "echo" {
|
|
foundEcho = true
|
|
}
|
|
if command.Trigger == "custom_command" {
|
|
foundCustom = true
|
|
}
|
|
}
|
|
require.True(t, foundEcho, "Couldn't find echo command")
|
|
require.True(t, foundCustom, "Should list the custom command")
|
|
}, "ListSystemAndCustomCommands")
|
|
|
|
th.TestForSystemAdminAndLocal(t, func(t *testing.T, c *model.Client4) {
|
|
listCommands, _, err := c.ListCommands(context.Background(), th.BasicTeam.Id, true)
|
|
require.NoError(t, err)
|
|
|
|
require.Len(t, listCommands, 1, "Should list just one custom command")
|
|
require.Equal(t, listCommands[0].Trigger, "custom_command", "Wrong custom command trigger")
|
|
}, "ListCustomOnlyCommands")
|
|
|
|
t.Run("UserWithNoPermissionForCustomCommands", func(t *testing.T) {
|
|
_, resp, err := client.ListCommands(context.Background(), th.BasicTeam.Id, true)
|
|
require.Error(t, err)
|
|
CheckForbiddenStatus(t, resp)
|
|
})
|
|
|
|
t.Run("RegularUserCanListOnlySystemCommands", func(t *testing.T) {
|
|
listCommands, _, err := client.ListCommands(context.Background(), th.BasicTeam.Id, false)
|
|
require.NoError(t, err)
|
|
|
|
foundEcho := false
|
|
foundCustom := false
|
|
for _, command := range listCommands {
|
|
if command.Trigger == "echo" {
|
|
foundEcho = true
|
|
}
|
|
if command.Trigger == "custom_command" {
|
|
foundCustom = true
|
|
}
|
|
}
|
|
require.True(t, foundEcho, "Couldn't find echo command")
|
|
require.False(t, foundCustom, "Should not list the custom command")
|
|
})
|
|
|
|
t.Run("NoMember", func(t *testing.T) {
|
|
client.Logout(context.Background())
|
|
user := th.CreateUser()
|
|
th.SystemAdminClient.RemoveTeamMember(context.Background(), th.BasicTeam.Id, user.Id)
|
|
client.Login(context.Background(), user.Email, user.Password)
|
|
_, resp, err := client.ListCommands(context.Background(), th.BasicTeam.Id, false)
|
|
require.Error(t, err)
|
|
CheckForbiddenStatus(t, resp)
|
|
_, resp, err = client.ListCommands(context.Background(), th.BasicTeam.Id, true)
|
|
require.Error(t, err)
|
|
CheckForbiddenStatus(t, resp)
|
|
})
|
|
|
|
t.Run("NotLoggedIn", func(t *testing.T) {
|
|
client.Logout(context.Background())
|
|
_, resp, err := client.ListCommands(context.Background(), th.BasicTeam.Id, false)
|
|
require.Error(t, err)
|
|
CheckUnauthorizedStatus(t, resp)
|
|
_, resp, err = client.ListCommands(context.Background(), th.BasicTeam.Id, true)
|
|
require.Error(t, err)
|
|
CheckUnauthorizedStatus(t, resp)
|
|
})
|
|
}
|
|
|
|
func TestListAutocompleteCommands(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
client := th.Client
|
|
|
|
newCmd := &model.Command{
|
|
CreatorId: th.BasicUser.Id,
|
|
TeamId: th.BasicTeam.Id,
|
|
URL: "http://nowhere.com",
|
|
Method: model.CommandMethodPost,
|
|
Trigger: "custom_command"}
|
|
|
|
_, _, err := th.SystemAdminClient.CreateCommand(context.Background(), newCmd)
|
|
require.NoError(t, err)
|
|
|
|
t.Run("ListAutocompleteCommandsOnly", func(t *testing.T) {
|
|
listCommands, _, err := th.SystemAdminClient.ListAutocompleteCommands(context.Background(), th.BasicTeam.Id)
|
|
require.NoError(t, err)
|
|
|
|
foundEcho := false
|
|
foundCustom := false
|
|
for _, command := range listCommands {
|
|
if command.Trigger == "echo" {
|
|
foundEcho = true
|
|
}
|
|
if command.Trigger == "custom_command" {
|
|
foundCustom = true
|
|
}
|
|
}
|
|
require.True(t, foundEcho, "Couldn't find echo command")
|
|
require.False(t, foundCustom, "Should not list the custom command")
|
|
})
|
|
|
|
t.Run("RegularUserCanListOnlySystemCommands", func(t *testing.T) {
|
|
listCommands, _, err := client.ListAutocompleteCommands(context.Background(), th.BasicTeam.Id)
|
|
require.NoError(t, err)
|
|
|
|
foundEcho := false
|
|
foundCustom := false
|
|
for _, command := range listCommands {
|
|
if command.Trigger == "echo" {
|
|
foundEcho = true
|
|
}
|
|
if command.Trigger == "custom_command" {
|
|
foundCustom = true
|
|
}
|
|
}
|
|
require.True(t, foundEcho, "Couldn't find echo command")
|
|
require.False(t, foundCustom, "Should not list the custom command")
|
|
})
|
|
|
|
t.Run("NoMember", func(t *testing.T) {
|
|
client.Logout(context.Background())
|
|
user := th.CreateUser()
|
|
th.SystemAdminClient.RemoveTeamMember(context.Background(), th.BasicTeam.Id, user.Id)
|
|
client.Login(context.Background(), user.Email, user.Password)
|
|
_, resp, err := client.ListAutocompleteCommands(context.Background(), th.BasicTeam.Id)
|
|
require.Error(t, err)
|
|
CheckForbiddenStatus(t, resp)
|
|
})
|
|
|
|
t.Run("NotLoggedIn", func(t *testing.T) {
|
|
client.Logout(context.Background())
|
|
_, resp, err := client.ListAutocompleteCommands(context.Background(), th.BasicTeam.Id)
|
|
require.Error(t, err)
|
|
CheckUnauthorizedStatus(t, resp)
|
|
})
|
|
}
|
|
|
|
func TestListCommandAutocompleteSuggestions(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
client := th.Client
|
|
|
|
newCmd := &model.Command{
|
|
CreatorId: th.BasicUser.Id,
|
|
TeamId: th.BasicTeam.Id,
|
|
URL: "http://nowhere.com",
|
|
Method: model.CommandMethodPost,
|
|
Trigger: "custom_command"}
|
|
|
|
_, _, err := th.SystemAdminClient.CreateCommand(context.Background(), newCmd)
|
|
require.NoError(t, err)
|
|
|
|
t.Run("ListAutocompleteSuggestionsOnly", func(t *testing.T) {
|
|
suggestions, _, err := th.SystemAdminClient.ListCommandAutocompleteSuggestions(context.Background(), "/", th.BasicTeam.Id)
|
|
require.NoError(t, err)
|
|
|
|
foundEcho := false
|
|
foundShrug := false
|
|
foundCustom := false
|
|
for _, command := range suggestions {
|
|
if command.Suggestion == "echo" {
|
|
foundEcho = true
|
|
}
|
|
if command.Suggestion == "shrug" {
|
|
foundShrug = true
|
|
}
|
|
if command.Suggestion == "custom_command" {
|
|
foundCustom = true
|
|
}
|
|
}
|
|
require.True(t, foundEcho, "Couldn't find echo command")
|
|
require.True(t, foundShrug, "Couldn't find shrug command")
|
|
require.False(t, foundCustom, "Should not list the custom command")
|
|
})
|
|
|
|
t.Run("ListAutocompleteSuggestionsOnlyWithInput", func(t *testing.T) {
|
|
suggestions, _, err := th.SystemAdminClient.ListCommandAutocompleteSuggestions(context.Background(), "/e", th.BasicTeam.Id)
|
|
require.NoError(t, err)
|
|
|
|
foundEcho := false
|
|
foundShrug := false
|
|
for _, command := range suggestions {
|
|
if command.Suggestion == "echo" {
|
|
foundEcho = true
|
|
}
|
|
if command.Suggestion == "shrug" {
|
|
foundShrug = true
|
|
}
|
|
}
|
|
require.True(t, foundEcho, "Couldn't find echo command")
|
|
require.False(t, foundShrug, "Should not list the shrug command")
|
|
})
|
|
|
|
t.Run("RegularUserCanListOnlySystemCommands", func(t *testing.T) {
|
|
suggestions, _, err := client.ListCommandAutocompleteSuggestions(context.Background(), "/", th.BasicTeam.Id)
|
|
require.NoError(t, err)
|
|
|
|
foundEcho := false
|
|
foundCustom := false
|
|
for _, suggestion := range suggestions {
|
|
if suggestion.Suggestion == "echo" {
|
|
foundEcho = true
|
|
}
|
|
if suggestion.Suggestion == "custom_command" {
|
|
foundCustom = true
|
|
}
|
|
}
|
|
require.True(t, foundEcho, "Couldn't find echo command")
|
|
require.False(t, foundCustom, "Should not list the custom command")
|
|
})
|
|
|
|
t.Run("NoMember", func(t *testing.T) {
|
|
client.Logout(context.Background())
|
|
user := th.CreateUser()
|
|
th.SystemAdminClient.RemoveTeamMember(context.Background(), th.BasicTeam.Id, user.Id)
|
|
client.Login(context.Background(), user.Email, user.Password)
|
|
_, resp, err := client.ListCommandAutocompleteSuggestions(context.Background(), "/", th.BasicTeam.Id)
|
|
require.Error(t, err)
|
|
CheckForbiddenStatus(t, resp)
|
|
})
|
|
|
|
t.Run("NotLoggedIn", func(t *testing.T) {
|
|
client.Logout(context.Background())
|
|
_, resp, err := client.ListCommandAutocompleteSuggestions(context.Background(), "/", th.BasicTeam.Id)
|
|
require.Error(t, err)
|
|
CheckUnauthorizedStatus(t, resp)
|
|
})
|
|
}
|
|
|
|
func TestGetCommand(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
|
|
enableCommands := *th.App.Config().ServiceSettings.EnableCommands
|
|
defer func() {
|
|
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableCommands = &enableCommands })
|
|
}()
|
|
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableCommands = true })
|
|
|
|
newCmd := &model.Command{
|
|
CreatorId: th.BasicUser.Id,
|
|
TeamId: th.BasicTeam.Id,
|
|
URL: "http://nowhere.com",
|
|
Method: model.CommandMethodPost,
|
|
Trigger: "roger"}
|
|
|
|
newCmd, _, err := th.SystemAdminClient.CreateCommand(context.Background(), newCmd)
|
|
require.NoError(t, err)
|
|
th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
|
|
t.Run("ValidId", func(t *testing.T) {
|
|
cmd, _, err := client.GetCommandById(context.Background(), newCmd.Id)
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, newCmd.Id, cmd.Id)
|
|
require.Equal(t, newCmd.CreatorId, cmd.CreatorId)
|
|
require.Equal(t, newCmd.TeamId, cmd.TeamId)
|
|
require.Equal(t, newCmd.URL, cmd.URL)
|
|
require.Equal(t, newCmd.Method, cmd.Method)
|
|
require.Equal(t, newCmd.Trigger, cmd.Trigger)
|
|
})
|
|
|
|
t.Run("InvalidId", func(t *testing.T) {
|
|
_, _, err := client.GetCommandById(context.Background(), strings.Repeat("z", len(newCmd.Id)))
|
|
require.Error(t, err)
|
|
})
|
|
})
|
|
t.Run("UserWithNoPermissionForCustomCommands", func(t *testing.T) {
|
|
_, resp, err := th.Client.GetCommandById(context.Background(), newCmd.Id)
|
|
require.Error(t, err)
|
|
CheckNotFoundStatus(t, resp)
|
|
})
|
|
|
|
t.Run("NoMember", func(t *testing.T) {
|
|
th.Client.Logout(context.Background())
|
|
user := th.CreateUser()
|
|
th.SystemAdminClient.RemoveTeamMember(context.Background(), th.BasicTeam.Id, user.Id)
|
|
th.Client.Login(context.Background(), user.Email, user.Password)
|
|
_, resp, err := th.Client.GetCommandById(context.Background(), newCmd.Id)
|
|
require.Error(t, err)
|
|
CheckNotFoundStatus(t, resp)
|
|
})
|
|
|
|
t.Run("NotLoggedIn", func(t *testing.T) {
|
|
th.Client.Logout(context.Background())
|
|
_, resp, err := th.Client.GetCommandById(context.Background(), newCmd.Id)
|
|
require.Error(t, err)
|
|
CheckUnauthorizedStatus(t, resp)
|
|
})
|
|
}
|
|
|
|
func TestRegenToken(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
client := th.Client
|
|
|
|
enableCommands := *th.App.Config().ServiceSettings.EnableCommands
|
|
defer func() {
|
|
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableCommands = &enableCommands })
|
|
}()
|
|
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableCommands = true })
|
|
|
|
newCmd := &model.Command{
|
|
CreatorId: th.BasicUser.Id,
|
|
TeamId: th.BasicTeam.Id,
|
|
URL: "http://nowhere.com",
|
|
Method: model.CommandMethodPost,
|
|
Trigger: "trigger"}
|
|
|
|
createdCmd, resp, err := th.SystemAdminClient.CreateCommand(context.Background(), newCmd)
|
|
require.NoError(t, err)
|
|
CheckCreatedStatus(t, resp)
|
|
|
|
token, _, err := th.SystemAdminClient.RegenCommandToken(context.Background(), createdCmd.Id)
|
|
require.NoError(t, err)
|
|
require.NotEqual(t, createdCmd.Token, token, "should update the token")
|
|
|
|
token, resp, err = client.RegenCommandToken(context.Background(), createdCmd.Id)
|
|
require.Error(t, err)
|
|
CheckNotFoundStatus(t, resp)
|
|
require.Empty(t, token, "should not return the token")
|
|
}
|
|
|
|
func TestExecuteInvalidCommand(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
client := th.Client
|
|
channel := th.BasicChannel
|
|
|
|
enableCommands := *th.App.Config().ServiceSettings.EnableCommands
|
|
allowedInternalConnections := *th.App.Config().ServiceSettings.AllowedUntrustedInternalConnections
|
|
defer func() {
|
|
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableCommands = &enableCommands })
|
|
th.App.UpdateConfig(func(cfg *model.Config) {
|
|
cfg.ServiceSettings.AllowedUntrustedInternalConnections = &allowedInternalConnections
|
|
})
|
|
}()
|
|
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableCommands = true })
|
|
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowedUntrustedInternalConnections = "127.0.0.0/8" })
|
|
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
rc := &model.CommandResponse{}
|
|
|
|
if err := json.NewEncoder(w).Encode(rc); err != nil {
|
|
th.TestLogger.Warn("Error while writing response", mlog.Err(err))
|
|
}
|
|
}))
|
|
defer ts.Close()
|
|
|
|
getCmd := &model.Command{
|
|
CreatorId: th.BasicUser.Id,
|
|
TeamId: th.BasicTeam.Id,
|
|
URL: ts.URL,
|
|
Method: model.CommandMethodGet,
|
|
Trigger: "getcommand",
|
|
}
|
|
|
|
_, appErr := th.App.CreateCommand(getCmd)
|
|
require.Nil(t, appErr, "failed to create get command")
|
|
|
|
_, resp, err := client.ExecuteCommand(context.Background(), channel.Id, "")
|
|
require.Error(t, err)
|
|
CheckBadRequestStatus(t, resp)
|
|
|
|
_, resp, err = client.ExecuteCommand(context.Background(), channel.Id, "/")
|
|
require.Error(t, err)
|
|
CheckBadRequestStatus(t, resp)
|
|
|
|
_, resp, err = client.ExecuteCommand(context.Background(), channel.Id, "getcommand")
|
|
require.Error(t, err)
|
|
CheckBadRequestStatus(t, resp)
|
|
|
|
_, resp, err = client.ExecuteCommand(context.Background(), channel.Id, "/junk")
|
|
require.Error(t, err)
|
|
CheckNotFoundStatus(t, resp)
|
|
|
|
otherUser := th.CreateUser()
|
|
client.Login(context.Background(), otherUser.Email, otherUser.Password)
|
|
|
|
_, resp, err = client.ExecuteCommand(context.Background(), channel.Id, "/getcommand")
|
|
require.Error(t, err)
|
|
CheckForbiddenStatus(t, resp)
|
|
|
|
client.Logout(context.Background())
|
|
|
|
_, resp, err = client.ExecuteCommand(context.Background(), channel.Id, "/getcommand")
|
|
require.Error(t, err)
|
|
CheckUnauthorizedStatus(t, resp)
|
|
|
|
_, _, err = th.SystemAdminClient.ExecuteCommand(context.Background(), channel.Id, "/getcommand")
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
func TestExecuteGetCommand(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
client := th.Client
|
|
channel := th.BasicChannel
|
|
|
|
enableCommands := *th.App.Config().ServiceSettings.EnableCommands
|
|
allowedInternalConnections := *th.App.Config().ServiceSettings.AllowedUntrustedInternalConnections
|
|
defer func() {
|
|
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableCommands = &enableCommands })
|
|
th.App.UpdateConfig(func(cfg *model.Config) {
|
|
cfg.ServiceSettings.AllowedUntrustedInternalConnections = &allowedInternalConnections
|
|
})
|
|
}()
|
|
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableCommands = true })
|
|
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowedUntrustedInternalConnections = "127.0.0.0/8" })
|
|
|
|
token := model.NewId()
|
|
expectedCommandResponse := &model.CommandResponse{
|
|
Text: "test get command response",
|
|
ResponseType: model.CommandResponseTypeInChannel,
|
|
Type: "custom_test",
|
|
Props: map[string]any{"someprop": "somevalue"},
|
|
}
|
|
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
require.Equal(t, http.MethodGet, r.Method)
|
|
|
|
values, err := url.ParseQuery(r.URL.RawQuery)
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, token, values.Get("token"))
|
|
require.Equal(t, th.BasicTeam.Name, values.Get("team_domain"))
|
|
require.Equal(t, "ourCommand", values.Get("cmd"))
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
if err := json.NewEncoder(w).Encode(expectedCommandResponse); err != nil {
|
|
th.TestLogger.Warn("Error while writing response", mlog.Err(err))
|
|
}
|
|
}))
|
|
defer ts.Close()
|
|
|
|
getCmd := &model.Command{
|
|
CreatorId: th.BasicUser.Id,
|
|
TeamId: th.BasicTeam.Id,
|
|
URL: ts.URL + "/?cmd=ourCommand",
|
|
Method: model.CommandMethodGet,
|
|
Trigger: "getcommand",
|
|
Token: token,
|
|
}
|
|
|
|
_, appErr := th.App.CreateCommand(getCmd)
|
|
require.Nil(t, appErr, "failed to create get command")
|
|
|
|
commandResponse, _, err := client.ExecuteCommand(context.Background(), channel.Id, "/getcommand")
|
|
require.NoError(t, err)
|
|
assert.True(t, len(commandResponse.TriggerId) == 26)
|
|
|
|
expectedCommandResponse.TriggerId = commandResponse.TriggerId
|
|
require.Equal(t, expectedCommandResponse, commandResponse)
|
|
}
|
|
|
|
func TestExecutePostCommand(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
client := th.Client
|
|
channel := th.BasicChannel
|
|
|
|
enableCommands := *th.App.Config().ServiceSettings.EnableCommands
|
|
allowedInternalConnections := *th.App.Config().ServiceSettings.AllowedUntrustedInternalConnections
|
|
defer func() {
|
|
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableCommands = &enableCommands })
|
|
th.App.UpdateConfig(func(cfg *model.Config) {
|
|
cfg.ServiceSettings.AllowedUntrustedInternalConnections = &allowedInternalConnections
|
|
})
|
|
}()
|
|
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableCommands = true })
|
|
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowedUntrustedInternalConnections = "127.0.0.0/8" })
|
|
|
|
token := model.NewId()
|
|
expectedCommandResponse := &model.CommandResponse{
|
|
Text: "test post command response",
|
|
ResponseType: model.CommandResponseTypeInChannel,
|
|
Type: "custom_test",
|
|
Props: map[string]any{"someprop": "somevalue"},
|
|
}
|
|
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
require.Equal(t, http.MethodPost, r.Method)
|
|
|
|
r.ParseForm()
|
|
|
|
require.Equal(t, token, r.FormValue("token"))
|
|
require.Equal(t, th.BasicTeam.Name, r.FormValue("team_domain"))
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
if err := json.NewEncoder(w).Encode(expectedCommandResponse); err != nil {
|
|
th.TestLogger.Warn("Error while writing response", mlog.Err(err))
|
|
}
|
|
}))
|
|
defer ts.Close()
|
|
|
|
postCmd := &model.Command{
|
|
CreatorId: th.BasicUser.Id,
|
|
TeamId: th.BasicTeam.Id,
|
|
URL: ts.URL,
|
|
Method: model.CommandMethodPost,
|
|
Trigger: "postcommand",
|
|
Token: token,
|
|
}
|
|
|
|
_, appErr := th.App.CreateCommand(postCmd)
|
|
require.Nil(t, appErr, "failed to create get command")
|
|
|
|
commandResponse, _, err := client.ExecuteCommand(context.Background(), channel.Id, "/postcommand")
|
|
require.NoError(t, err)
|
|
assert.True(t, len(commandResponse.TriggerId) == 26)
|
|
|
|
expectedCommandResponse.TriggerId = commandResponse.TriggerId
|
|
require.Equal(t, expectedCommandResponse, commandResponse)
|
|
}
|
|
|
|
func TestExecuteCommandAgainstChannelOnAnotherTeam(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
client := th.Client
|
|
channel := th.BasicChannel
|
|
|
|
enableCommands := *th.App.Config().ServiceSettings.EnableCommands
|
|
allowedInternalConnections := *th.App.Config().ServiceSettings.AllowedUntrustedInternalConnections
|
|
defer func() {
|
|
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableCommands = &enableCommands })
|
|
th.App.UpdateConfig(func(cfg *model.Config) {
|
|
cfg.ServiceSettings.AllowedUntrustedInternalConnections = &allowedInternalConnections
|
|
})
|
|
}()
|
|
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableCommands = true })
|
|
th.App.UpdateConfig(func(cfg *model.Config) {
|
|
*cfg.ServiceSettings.AllowedUntrustedInternalConnections = "localhost,127.0.0.1"
|
|
})
|
|
|
|
expectedCommandResponse := &model.CommandResponse{
|
|
Text: "test post command response",
|
|
ResponseType: model.CommandResponseTypeInChannel,
|
|
Type: "custom_test",
|
|
Props: map[string]any{"someprop": "somevalue"},
|
|
}
|
|
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
if err := json.NewEncoder(w).Encode(expectedCommandResponse); err != nil {
|
|
th.TestLogger.Warn("Error while writing response", mlog.Err(err))
|
|
}
|
|
}))
|
|
defer ts.Close()
|
|
|
|
// create a slash command on some other team where we have permission to do so
|
|
team2 := th.CreateTeam()
|
|
postCmd := &model.Command{
|
|
CreatorId: th.BasicUser.Id,
|
|
TeamId: team2.Id,
|
|
URL: ts.URL,
|
|
Method: model.CommandMethodPost,
|
|
Trigger: "postcommand",
|
|
}
|
|
_, appErr := th.App.CreateCommand(postCmd)
|
|
require.Nil(t, appErr, "failed to create post command")
|
|
|
|
// the execute command endpoint will always search for the command by trigger and team id, inferring team id from the
|
|
// channel id, so there is no way to use that slash command on a channel that belongs to some other team
|
|
_, resp, err := client.ExecuteCommand(context.Background(), channel.Id, "/postcommand")
|
|
require.Error(t, err)
|
|
CheckNotFoundStatus(t, resp)
|
|
}
|
|
|
|
func TestExecuteCommandAgainstChannelUserIsNotIn(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
client := th.Client
|
|
|
|
enableCommands := *th.App.Config().ServiceSettings.EnableCommands
|
|
allowedInternalConnections := *th.App.Config().ServiceSettings.AllowedUntrustedInternalConnections
|
|
defer func() {
|
|
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableCommands = &enableCommands })
|
|
th.App.UpdateConfig(func(cfg *model.Config) {
|
|
cfg.ServiceSettings.AllowedUntrustedInternalConnections = &allowedInternalConnections
|
|
})
|
|
}()
|
|
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableCommands = true })
|
|
th.App.UpdateConfig(func(cfg *model.Config) {
|
|
*cfg.ServiceSettings.AllowedUntrustedInternalConnections = "localhost,127.0.0.1"
|
|
})
|
|
|
|
expectedCommandResponse := &model.CommandResponse{
|
|
Text: "test post command response",
|
|
ResponseType: model.CommandResponseTypeInChannel,
|
|
Type: "custom_test",
|
|
Props: map[string]any{"someprop": "somevalue"},
|
|
}
|
|
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
if err := json.NewEncoder(w).Encode(expectedCommandResponse); err != nil {
|
|
th.TestLogger.Warn("Error while writing response", mlog.Err(err))
|
|
}
|
|
}))
|
|
defer ts.Close()
|
|
|
|
// create a slash command on some other team where we have permission to do so
|
|
team2 := th.CreateTeam()
|
|
postCmd := &model.Command{
|
|
CreatorId: th.BasicUser.Id,
|
|
TeamId: team2.Id,
|
|
URL: ts.URL,
|
|
Method: model.CommandMethodPost,
|
|
Trigger: "postcommand",
|
|
}
|
|
_, appErr := th.App.CreateCommand(postCmd)
|
|
require.Nil(t, appErr, "failed to create post command")
|
|
|
|
// make a channel on that team, ensuring that our test user isn't in it
|
|
channel2 := th.CreateChannelWithClientAndTeam(client, model.ChannelTypeOpen, team2.Id)
|
|
_, err := th.Client.RemoveUserFromChannel(context.Background(), channel2.Id, th.BasicUser.Id)
|
|
require.NoError(t, err, "Failed to remove user from channel")
|
|
|
|
// we should not be able to run the slash command in channel2, because we aren't in it
|
|
_, resp, err := client.ExecuteCommandWithTeam(context.Background(), channel2.Id, team2.Id, "/postcommand")
|
|
require.Error(t, err)
|
|
CheckForbiddenStatus(t, resp)
|
|
}
|
|
|
|
func TestExecuteCommandInDirectMessageChannel(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
client := th.Client
|
|
|
|
enableCommands := *th.App.Config().ServiceSettings.EnableCommands
|
|
allowedInternalConnections := *th.App.Config().ServiceSettings.AllowedUntrustedInternalConnections
|
|
defer func() {
|
|
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableCommands = &enableCommands })
|
|
th.App.UpdateConfig(func(cfg *model.Config) {
|
|
cfg.ServiceSettings.AllowedUntrustedInternalConnections = &allowedInternalConnections
|
|
})
|
|
}()
|
|
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableCommands = true })
|
|
th.App.UpdateConfig(func(cfg *model.Config) {
|
|
*cfg.ServiceSettings.AllowedUntrustedInternalConnections = "localhost,127.0.0.1"
|
|
})
|
|
|
|
// create a team that the user isn't a part of
|
|
team2 := th.CreateTeam()
|
|
|
|
expectedCommandResponse := &model.CommandResponse{
|
|
Text: "test post command response",
|
|
ResponseType: model.CommandResponseTypeInChannel,
|
|
Type: "custom_test",
|
|
Props: map[string]any{"someprop": "somevalue"},
|
|
}
|
|
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
require.Equal(t, http.MethodPost, r.Method)
|
|
w.Header().Set("Content-Type", "application/json")
|
|
if err := json.NewEncoder(w).Encode(expectedCommandResponse); err != nil {
|
|
th.TestLogger.Warn("Error while writing response", mlog.Err(err))
|
|
}
|
|
}))
|
|
defer ts.Close()
|
|
|
|
// create a slash command on some other team where we have permission to do so
|
|
postCmd := &model.Command{
|
|
CreatorId: th.BasicUser.Id,
|
|
TeamId: team2.Id,
|
|
URL: ts.URL,
|
|
Method: model.CommandMethodPost,
|
|
Trigger: "postcommand",
|
|
}
|
|
_, appErr := th.App.CreateCommand(postCmd)
|
|
require.Nil(t, appErr, "failed to create post command")
|
|
|
|
// make a direct message channel
|
|
dmChannel, response, err := client.CreateDirectChannel(context.Background(), th.BasicUser.Id, th.BasicUser2.Id)
|
|
require.NoError(t, err)
|
|
CheckCreatedStatus(t, response)
|
|
|
|
// we should be able to run the slash command in the DM channel
|
|
_, resp, err := client.ExecuteCommandWithTeam(context.Background(), dmChannel.Id, team2.Id, "/postcommand")
|
|
require.NoError(t, err)
|
|
CheckOKStatus(t, resp)
|
|
|
|
// but we can't run the slash command in the DM channel if we sub in some other team's id
|
|
_, resp, err = client.ExecuteCommandWithTeam(context.Background(), dmChannel.Id, th.BasicTeam.Id, "/postcommand")
|
|
require.Error(t, err)
|
|
CheckNotFoundStatus(t, resp)
|
|
}
|
|
|
|
func TestExecuteCommandInTeamUserIsNotOn(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
client := th.Client
|
|
|
|
enableCommands := *th.App.Config().ServiceSettings.EnableCommands
|
|
allowedInternalConnections := *th.App.Config().ServiceSettings.AllowedUntrustedInternalConnections
|
|
defer func() {
|
|
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableCommands = &enableCommands })
|
|
th.App.UpdateConfig(func(cfg *model.Config) {
|
|
cfg.ServiceSettings.AllowedUntrustedInternalConnections = &allowedInternalConnections
|
|
})
|
|
}()
|
|
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableCommands = true })
|
|
th.App.UpdateConfig(func(cfg *model.Config) {
|
|
*cfg.ServiceSettings.AllowedUntrustedInternalConnections = "localhost,127.0.0.1"
|
|
})
|
|
|
|
// create a team that the user isn't a part of
|
|
team2 := th.CreateTeam()
|
|
|
|
expectedCommandResponse := &model.CommandResponse{
|
|
Text: "test post command response",
|
|
ResponseType: model.CommandResponseTypeInChannel,
|
|
Type: "custom_test",
|
|
Props: map[string]any{"someprop": "somevalue"},
|
|
}
|
|
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
require.Equal(t, http.MethodPost, r.Method)
|
|
r.ParseForm()
|
|
require.Equal(t, team2.Name, r.FormValue("team_domain"))
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
if err := json.NewEncoder(w).Encode(expectedCommandResponse); err != nil {
|
|
th.TestLogger.Warn("Error while writing response", mlog.Err(err))
|
|
}
|
|
}))
|
|
defer ts.Close()
|
|
|
|
// create a slash command on that team
|
|
postCmd := &model.Command{
|
|
CreatorId: th.BasicUser.Id,
|
|
TeamId: team2.Id,
|
|
URL: ts.URL,
|
|
Method: model.CommandMethodPost,
|
|
Trigger: "postcommand",
|
|
}
|
|
_, appErr := th.App.CreateCommand(postCmd)
|
|
require.Nil(t, appErr, "failed to create post command")
|
|
|
|
// make a direct message channel
|
|
dmChannel, response, err := client.CreateDirectChannel(context.Background(), th.BasicUser.Id, th.BasicUser2.Id)
|
|
require.NoError(t, err)
|
|
CheckCreatedStatus(t, response)
|
|
|
|
// we should be able to run the slash command in the DM channel
|
|
_, resp, err := client.ExecuteCommandWithTeam(context.Background(), dmChannel.Id, team2.Id, "/postcommand")
|
|
require.NoError(t, err)
|
|
CheckOKStatus(t, resp)
|
|
|
|
// if the user is removed from the team, they should NOT be able to run the slash command in the DM channel
|
|
_, err = th.Client.RemoveTeamMember(context.Background(), team2.Id, th.BasicUser.Id)
|
|
require.NoError(t, err, "Failed to remove user from team")
|
|
|
|
_, resp, err = client.ExecuteCommandWithTeam(context.Background(), dmChannel.Id, team2.Id, "/postcommand")
|
|
require.Error(t, err)
|
|
CheckForbiddenStatus(t, resp)
|
|
|
|
// if we omit the team id from the request, the slash command will fail because this is a DM channel, and the
|
|
// team id can't be inherited from the channel
|
|
_, resp, err = client.ExecuteCommand(context.Background(), dmChannel.Id, "/postcommand")
|
|
require.Error(t, err)
|
|
CheckForbiddenStatus(t, resp)
|
|
}
|
|
|
|
func TestExecuteCommandReadOnly(t *testing.T) {
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
client := th.Client
|
|
|
|
enableCommands := *th.App.Config().ServiceSettings.EnableCommands
|
|
allowedInternalConnections := *th.App.Config().ServiceSettings.AllowedUntrustedInternalConnections
|
|
defer func() {
|
|
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableCommands = &enableCommands })
|
|
th.App.UpdateConfig(func(cfg *model.Config) {
|
|
cfg.ServiceSettings.AllowedUntrustedInternalConnections = &allowedInternalConnections
|
|
})
|
|
}()
|
|
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableCommands = true })
|
|
th.App.UpdateConfig(func(cfg *model.Config) {
|
|
*cfg.ServiceSettings.AllowedUntrustedInternalConnections = "localhost,127.0.0.1"
|
|
})
|
|
|
|
expectedCommandResponse := &model.CommandResponse{
|
|
Text: "test post command response",
|
|
ResponseType: model.CommandResponseTypeInChannel,
|
|
Type: "custom_test",
|
|
Props: map[string]any{"someprop": "somevalue"},
|
|
}
|
|
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
require.Equal(t, http.MethodPost, r.Method)
|
|
r.ParseForm()
|
|
require.Equal(t, th.BasicTeam.Name, r.FormValue("team_domain"))
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
if err := json.NewEncoder(w).Encode(expectedCommandResponse); err != nil {
|
|
th.TestLogger.Warn("Error while writing response", mlog.Err(err))
|
|
}
|
|
}))
|
|
defer ts.Close()
|
|
|
|
// create a slash command on that team
|
|
postCmd := &model.Command{
|
|
CreatorId: th.BasicUser.Id,
|
|
TeamId: th.BasicTeam.Id,
|
|
URL: ts.URL,
|
|
Method: model.CommandMethodPost,
|
|
Trigger: "postcommand",
|
|
}
|
|
_, appErr := th.App.CreateCommand(postCmd)
|
|
require.Nil(t, appErr, "failed to create post command")
|
|
|
|
// Confirm that the command works when the channel is not read only
|
|
_, resp, err := client.ExecuteCommandWithTeam(context.Background(), th.BasicChannel.Id, th.BasicChannel.TeamId, "/postcommand")
|
|
require.NoError(t, err)
|
|
CheckOKStatus(t, resp)
|
|
|
|
// Enable Enterprise features
|
|
th.App.Srv().SetLicense(model.NewTestLicense())
|
|
|
|
th.App.SetPhase2PermissionsMigrationStatus(true)
|
|
|
|
_, appErr = th.App.PatchChannelModerationsForChannel(
|
|
th.Context,
|
|
th.BasicChannel,
|
|
[]*model.ChannelModerationPatch{{
|
|
Name: &model.PermissionCreatePost.Id,
|
|
Roles: &model.ChannelModeratedRolesPatch{
|
|
Guests: model.NewBool(false),
|
|
Members: model.NewBool(false),
|
|
},
|
|
}})
|
|
require.Nil(t, appErr)
|
|
|
|
// Confirm that the command fails when the channel is read only
|
|
_, resp, err = client.ExecuteCommandWithTeam(context.Background(), th.BasicChannel.Id, th.BasicChannel.TeamId, "/postcommand")
|
|
require.Error(t, err)
|
|
CheckForbiddenStatus(t, resp)
|
|
}
|