Update slash command permission (#22468)

* Update slash command permission

* Fix permission
This commit is contained in:
Ben Schumacher 2023-04-18 21:54:20 +02:00 committed by GitHub
parent 9b81c08622
commit 84a3042249
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 96 additions and 1 deletions

View File

@ -323,7 +323,14 @@ func executeCommand(c *Context, w http.ResponseWriter, r *http.Request) {
defer c.LogAuditRec(auditRec)
audit.AddEventParameterAuditable(auditRec, "command_args", &commandArgs)
// checks that user is a member of the specified channel, and that they have permission to use slash commands in it
// Checks that user is a member of the specified channel, and that they have permission to create a post in it.
if !c.App.SessionHasPermissionToChannel(c.AppContext, *c.AppContext.Session(), commandArgs.ChannelId, model.PermissionCreatePost) {
c.SetPermissionError(model.PermissionCreatePost)
return
}
// For compatibility reasons, PermissionCreatePost is also checked.
// TODO: Remove in 8.0: https://mattermost.atlassian.net/browse/MM-51274
if !c.App.SessionHasPermissionToChannel(c.AppContext, *c.AppContext.Session(), commandArgs.ChannelId, model.PermissionUseSlashCommands) {
c.SetPermissionError(model.PermissionUseSlashCommands)
return
@ -343,6 +350,13 @@ func executeCommand(c *Context, w http.ResponseWriter, r *http.Request) {
// if the slash command was used in a DM or GM, ensure that the user is a member of the specified team, so that
// they can't just execute slash commands against arbitrary teams
if c.AppContext.Session().GetTeamByTeamId(commandArgs.TeamId) == nil {
if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionCreatePost) {
c.SetPermissionError(model.PermissionCreatePost)
return
}
// For compatibility reasons, PermissionCreatePost is also checked.
// TODO: Remove in 8.0: https://mattermost.atlassian.net/browse/MM-51274
if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionUseSlashCommands) {
c.SetPermissionError(model.PermissionUseSlashCommands)
return

View File

@ -14,6 +14,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/mattermost/mattermost-server/server/v8/channels/app/request"
"github.com/mattermost/mattermost-server/server/v8/model"
"github.com/mattermost/mattermost-server/server/v8/platform/shared/mlog"
)
@ -1065,3 +1066,80 @@ func TestExecuteCommandInTeamUserIsNotOn(t *testing.T) {
require.Error(t, err)
CheckForbiddenStatus(t, resp)
}
func TestExecuteCommandReadOnly(t *testing.T) {
th := Setup(t).InitBasic()
ctx := request.EmptyContext(th.TestLogger)
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(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(
ctx,
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(th.BasicChannel.Id, th.BasicChannel.TeamId, "/postcommand")
require.Error(t, err)
CheckForbiddenStatus(t, resp)
}

View File

@ -21,6 +21,9 @@ type Permission struct {
var PermissionInviteUser *Permission
var PermissionAddUserToTeam *Permission
// Deprecated: PermissionCreatePost should be used to determine if a slash command can be executed.
// TODO: Remove in 8.0: https://mattermost.atlassian.net/browse/MM-51274
var PermissionUseSlashCommands *Permission
var PermissionManageSlashCommands *Permission
var PermissionManageOthersSlashCommands *Permission