github.com/kongr45gpen/mattermost-server@v5.11.1+incompatible/api4/command.go (about) 1 // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package api4 5 6 import ( 7 "net/http" 8 "strconv" 9 "strings" 10 11 "github.com/mattermost/mattermost-server/model" 12 ) 13 14 func (api *API) InitCommand() { 15 api.BaseRoutes.Commands.Handle("", api.ApiSessionRequired(createCommand)).Methods("POST") 16 api.BaseRoutes.Commands.Handle("", api.ApiSessionRequired(listCommands)).Methods("GET") 17 api.BaseRoutes.Commands.Handle("/execute", api.ApiSessionRequired(executeCommand)).Methods("POST") 18 19 api.BaseRoutes.Command.Handle("", api.ApiSessionRequired(updateCommand)).Methods("PUT") 20 api.BaseRoutes.Command.Handle("", api.ApiSessionRequired(deleteCommand)).Methods("DELETE") 21 22 api.BaseRoutes.Team.Handle("/commands/autocomplete", api.ApiSessionRequired(listAutocompleteCommands)).Methods("GET") 23 api.BaseRoutes.Command.Handle("/regen_token", api.ApiSessionRequired(regenCommandToken)).Methods("PUT") 24 } 25 26 func createCommand(c *Context, w http.ResponseWriter, r *http.Request) { 27 cmd := model.CommandFromJson(r.Body) 28 if cmd == nil { 29 c.SetInvalidParam("command") 30 return 31 } 32 33 c.LogAudit("attempt") 34 35 if !c.App.SessionHasPermissionToTeam(c.App.Session, cmd.TeamId, model.PERMISSION_MANAGE_SLASH_COMMANDS) { 36 c.SetPermissionError(model.PERMISSION_MANAGE_SLASH_COMMANDS) 37 return 38 } 39 40 cmd.CreatorId = c.App.Session.UserId 41 42 rcmd, err := c.App.CreateCommand(cmd) 43 if err != nil { 44 c.Err = err 45 return 46 } 47 48 c.LogAudit("success") 49 w.WriteHeader(http.StatusCreated) 50 w.Write([]byte(rcmd.ToJson())) 51 } 52 53 func updateCommand(c *Context, w http.ResponseWriter, r *http.Request) { 54 c.RequireCommandId() 55 if c.Err != nil { 56 return 57 } 58 59 cmd := model.CommandFromJson(r.Body) 60 if cmd == nil || cmd.Id != c.Params.CommandId { 61 c.SetInvalidParam("command") 62 return 63 } 64 65 c.LogAudit("attempt") 66 67 oldCmd, err := c.App.GetCommand(c.Params.CommandId) 68 if err != nil { 69 c.Err = err 70 return 71 } 72 73 if cmd.TeamId != oldCmd.TeamId { 74 c.Err = model.NewAppError("updateCommand", "api.command.team_mismatch.app_error", nil, "user_id="+c.App.Session.UserId, http.StatusBadRequest) 75 return 76 } 77 78 if !c.App.SessionHasPermissionToTeam(c.App.Session, oldCmd.TeamId, model.PERMISSION_MANAGE_SLASH_COMMANDS) { 79 c.LogAudit("fail - inappropriate permissions") 80 c.SetPermissionError(model.PERMISSION_MANAGE_SLASH_COMMANDS) 81 return 82 } 83 84 if c.App.Session.UserId != oldCmd.CreatorId && !c.App.SessionHasPermissionToTeam(c.App.Session, oldCmd.TeamId, model.PERMISSION_MANAGE_OTHERS_SLASH_COMMANDS) { 85 c.LogAudit("fail - inappropriate permissions") 86 c.SetPermissionError(model.PERMISSION_MANAGE_OTHERS_SLASH_COMMANDS) 87 return 88 } 89 90 rcmd, err := c.App.UpdateCommand(oldCmd, cmd) 91 if err != nil { 92 c.Err = err 93 return 94 } 95 96 c.LogAudit("success") 97 98 w.Write([]byte(rcmd.ToJson())) 99 } 100 101 func deleteCommand(c *Context, w http.ResponseWriter, r *http.Request) { 102 c.RequireCommandId() 103 if c.Err != nil { 104 return 105 } 106 107 c.LogAudit("attempt") 108 109 cmd, err := c.App.GetCommand(c.Params.CommandId) 110 if err != nil { 111 c.Err = err 112 return 113 } 114 115 if !c.App.SessionHasPermissionToTeam(c.App.Session, cmd.TeamId, model.PERMISSION_MANAGE_SLASH_COMMANDS) { 116 c.LogAudit("fail - inappropriate permissions") 117 c.SetPermissionError(model.PERMISSION_MANAGE_SLASH_COMMANDS) 118 return 119 } 120 121 if c.App.Session.UserId != cmd.CreatorId && !c.App.SessionHasPermissionToTeam(c.App.Session, cmd.TeamId, model.PERMISSION_MANAGE_OTHERS_SLASH_COMMANDS) { 122 c.LogAudit("fail - inappropriate permissions") 123 c.SetPermissionError(model.PERMISSION_MANAGE_OTHERS_SLASH_COMMANDS) 124 return 125 } 126 127 err = c.App.DeleteCommand(cmd.Id) 128 if err != nil { 129 c.Err = err 130 return 131 } 132 133 c.LogAudit("success") 134 135 ReturnStatusOK(w) 136 } 137 138 func listCommands(c *Context, w http.ResponseWriter, r *http.Request) { 139 customOnly, failConv := strconv.ParseBool(r.URL.Query().Get("custom_only")) 140 if failConv != nil { 141 customOnly = false 142 } 143 144 teamId := r.URL.Query().Get("team_id") 145 146 if len(teamId) == 0 { 147 c.SetInvalidParam("team_id") 148 return 149 } 150 151 var commands []*model.Command 152 var err *model.AppError 153 if customOnly { 154 if !c.App.SessionHasPermissionToTeam(c.App.Session, teamId, model.PERMISSION_MANAGE_SLASH_COMMANDS) { 155 c.SetPermissionError(model.PERMISSION_MANAGE_SLASH_COMMANDS) 156 return 157 } 158 commands, err = c.App.ListTeamCommands(teamId) 159 if err != nil { 160 c.Err = err 161 return 162 } 163 } else { 164 //User with no permission should see only system commands 165 if !c.App.SessionHasPermissionToTeam(c.App.Session, teamId, model.PERMISSION_MANAGE_SLASH_COMMANDS) { 166 commands, err = c.App.ListAutocompleteCommands(teamId, c.App.T) 167 if err != nil { 168 c.Err = err 169 return 170 } 171 } else { 172 commands, err = c.App.ListAllCommands(teamId, c.App.T) 173 if err != nil { 174 c.Err = err 175 return 176 } 177 } 178 } 179 180 w.Write([]byte(model.CommandListToJson(commands))) 181 } 182 183 func executeCommand(c *Context, w http.ResponseWriter, r *http.Request) { 184 commandArgs := model.CommandArgsFromJson(r.Body) 185 if commandArgs == nil { 186 c.SetInvalidParam("command_args") 187 return 188 } 189 190 if len(commandArgs.Command) <= 1 || strings.Index(commandArgs.Command, "/") != 0 || len(commandArgs.ChannelId) != 26 { 191 c.Err = model.NewAppError("executeCommand", "api.command.execute_command.start.app_error", nil, "", http.StatusBadRequest) 192 return 193 } 194 195 // checks that user is a member of the specified channel, and that they have permission to use slash commands in it 196 if !c.App.SessionHasPermissionToChannel(c.App.Session, commandArgs.ChannelId, model.PERMISSION_USE_SLASH_COMMANDS) { 197 c.SetPermissionError(model.PERMISSION_USE_SLASH_COMMANDS) 198 return 199 } 200 201 channel, err := c.App.GetChannel(commandArgs.ChannelId) 202 if err != nil { 203 c.Err = err 204 return 205 } 206 207 if channel.Type != model.CHANNEL_DIRECT && channel.Type != model.CHANNEL_GROUP { 208 // if this isn't a DM or GM, the team id is implicitly taken from the channel so that slash commands created on 209 // some other team can't be run against this one 210 commandArgs.TeamId = channel.TeamId 211 } else { 212 // if the slash command was used in a DM or GM, ensure that the user is a member of the specified team, so that 213 // they can't just execute slash commands against arbitrary teams 214 if c.App.Session.GetTeamByTeamId(commandArgs.TeamId) == nil { 215 if !c.App.SessionHasPermissionTo(c.App.Session, model.PERMISSION_USE_SLASH_COMMANDS) { 216 c.SetPermissionError(model.PERMISSION_USE_SLASH_COMMANDS) 217 return 218 } 219 } 220 } 221 222 commandArgs.UserId = c.App.Session.UserId 223 commandArgs.T = c.App.T 224 commandArgs.Session = c.App.Session 225 commandArgs.SiteURL = c.GetSiteURLHeader() 226 227 response, err := c.App.ExecuteCommand(commandArgs) 228 if err != nil { 229 c.Err = err 230 return 231 } 232 233 w.Write([]byte(response.ToJson())) 234 } 235 236 func listAutocompleteCommands(c *Context, w http.ResponseWriter, r *http.Request) { 237 c.RequireTeamId() 238 if c.Err != nil { 239 return 240 } 241 242 if !c.App.SessionHasPermissionToTeam(c.App.Session, c.Params.TeamId, model.PERMISSION_VIEW_TEAM) { 243 c.SetPermissionError(model.PERMISSION_VIEW_TEAM) 244 return 245 } 246 247 commands, err := c.App.ListAutocompleteCommands(c.Params.TeamId, c.App.T) 248 if err != nil { 249 c.Err = err 250 return 251 } 252 253 w.Write([]byte(model.CommandListToJson(commands))) 254 } 255 256 func regenCommandToken(c *Context, w http.ResponseWriter, r *http.Request) { 257 c.RequireCommandId() 258 if c.Err != nil { 259 return 260 } 261 262 c.LogAudit("attempt") 263 cmd, err := c.App.GetCommand(c.Params.CommandId) 264 if err != nil { 265 c.Err = err 266 return 267 } 268 269 if !c.App.SessionHasPermissionToTeam(c.App.Session, cmd.TeamId, model.PERMISSION_MANAGE_SLASH_COMMANDS) { 270 c.LogAudit("fail - inappropriate permissions") 271 c.SetPermissionError(model.PERMISSION_MANAGE_SLASH_COMMANDS) 272 return 273 } 274 275 if c.App.Session.UserId != cmd.CreatorId && !c.App.SessionHasPermissionToTeam(c.App.Session, cmd.TeamId, model.PERMISSION_MANAGE_OTHERS_SLASH_COMMANDS) { 276 c.LogAudit("fail - inappropriate permissions") 277 c.SetPermissionError(model.PERMISSION_MANAGE_OTHERS_SLASH_COMMANDS) 278 return 279 } 280 281 rcmd, err := c.App.RegenCommandToken(cmd) 282 if err != nil { 283 c.Err = err 284 return 285 } 286 287 resp := make(map[string]string) 288 resp["token"] = rcmd.Token 289 290 w.Write([]byte(model.MapToJson(resp))) 291 }