github.com/adacta-ru/mattermost-server/v6@v6.0.0/api4/bot.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package api4 5 6 import ( 7 "fmt" 8 "io" 9 "io/ioutil" 10 "net/http" 11 "strconv" 12 13 "github.com/adacta-ru/mattermost-server/v6/audit" 14 "github.com/adacta-ru/mattermost-server/v6/model" 15 ) 16 17 func (api *API) InitBot() { 18 api.BaseRoutes.Bots.Handle("", api.ApiSessionRequired(createBot)).Methods("POST") 19 api.BaseRoutes.Bot.Handle("", api.ApiSessionRequired(patchBot)).Methods("PUT") 20 api.BaseRoutes.Bot.Handle("", api.ApiSessionRequired(getBot)).Methods("GET") 21 api.BaseRoutes.Bots.Handle("", api.ApiSessionRequired(getBots)).Methods("GET") 22 api.BaseRoutes.Bot.Handle("/disable", api.ApiSessionRequired(disableBot)).Methods("POST") 23 api.BaseRoutes.Bot.Handle("/enable", api.ApiSessionRequired(enableBot)).Methods("POST") 24 api.BaseRoutes.Bot.Handle("/convert_to_user", api.ApiSessionRequired(convertBotToUser)).Methods("POST") 25 api.BaseRoutes.Bot.Handle("/assign/{user_id:[A-Za-z0-9]+}", api.ApiSessionRequired(assignBot)).Methods("POST") 26 27 api.BaseRoutes.Bot.Handle("/icon", api.ApiSessionRequiredTrustRequester(getBotIconImage)).Methods("GET") 28 api.BaseRoutes.Bot.Handle("/icon", api.ApiSessionRequired(setBotIconImage)).Methods("POST") 29 api.BaseRoutes.Bot.Handle("/icon", api.ApiSessionRequired(deleteBotIconImage)).Methods("DELETE") 30 } 31 32 func createBot(c *Context, w http.ResponseWriter, r *http.Request) { 33 botPatch := model.BotPatchFromJson(r.Body) 34 if botPatch == nil { 35 c.SetInvalidParam("bot") 36 return 37 } 38 39 bot := &model.Bot{ 40 OwnerId: c.App.Session().UserId, 41 } 42 bot.Patch(botPatch) 43 44 auditRec := c.MakeAuditRecord("createBot", audit.Fail) 45 defer c.LogAuditRec(auditRec) 46 auditRec.AddMeta("bot", bot) 47 48 if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_CREATE_BOT) { 49 c.SetPermissionError(model.PERMISSION_CREATE_BOT) 50 return 51 } 52 53 if user, err := c.App.GetUser(c.App.Session().UserId); err == nil { 54 if user.IsBot { 55 c.SetPermissionError(model.PERMISSION_CREATE_BOT) 56 return 57 } 58 } 59 60 if !*c.App.Config().ServiceSettings.EnableBotAccountCreation { 61 c.Err = model.NewAppError("createBot", "api.bot.create_disabled", nil, "", http.StatusForbidden) 62 return 63 } 64 65 createdBot, err := c.App.CreateBot(bot) 66 if err != nil { 67 c.Err = err 68 return 69 } 70 71 auditRec.Success() 72 auditRec.AddMeta("bot", createdBot) // overwrite meta 73 74 w.WriteHeader(http.StatusCreated) 75 w.Write(createdBot.ToJson()) 76 } 77 78 func patchBot(c *Context, w http.ResponseWriter, r *http.Request) { 79 c.RequireBotUserId() 80 if c.Err != nil { 81 return 82 } 83 botUserId := c.Params.BotUserId 84 85 botPatch := model.BotPatchFromJson(r.Body) 86 if botPatch == nil { 87 c.SetInvalidParam("bot") 88 return 89 } 90 91 auditRec := c.MakeAuditRecord("patchBot", audit.Fail) 92 defer c.LogAuditRec(auditRec) 93 auditRec.AddMeta("bot_id", botUserId) 94 95 if err := c.App.SessionHasPermissionToManageBot(*c.App.Session(), botUserId); err != nil { 96 c.Err = err 97 return 98 } 99 100 updatedBot, err := c.App.PatchBot(botUserId, botPatch) 101 if err != nil { 102 c.Err = err 103 return 104 } 105 106 auditRec.Success() 107 auditRec.AddMeta("bot", updatedBot) 108 109 w.Write(updatedBot.ToJson()) 110 } 111 112 func getBot(c *Context, w http.ResponseWriter, r *http.Request) { 113 c.RequireBotUserId() 114 if c.Err != nil { 115 return 116 } 117 botUserId := c.Params.BotUserId 118 119 includeDeleted, _ := strconv.ParseBool(r.URL.Query().Get("include_deleted")) 120 121 bot, appErr := c.App.GetBot(botUserId, includeDeleted) 122 if appErr != nil { 123 c.Err = appErr 124 return 125 } 126 127 if c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_READ_OTHERS_BOTS) { 128 // Allow access to any bot. 129 } else if bot.OwnerId == c.App.Session().UserId { 130 if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_READ_BOTS) { 131 // Pretend like the bot doesn't exist at all to avoid revealing that the 132 // user is a bot. It's kind of silly in this case, sine we created the bot, 133 // but we don't have read bot permissions. 134 c.Err = model.MakeBotNotFoundError(botUserId) 135 return 136 } 137 } else { 138 // Pretend like the bot doesn't exist at all, to avoid revealing that the 139 // user is a bot. 140 c.Err = model.MakeBotNotFoundError(botUserId) 141 return 142 } 143 144 if c.HandleEtag(bot.Etag(), "Get Bot", w, r) { 145 return 146 } 147 148 w.Write(bot.ToJson()) 149 } 150 151 func getBots(c *Context, w http.ResponseWriter, r *http.Request) { 152 includeDeleted, _ := strconv.ParseBool(r.URL.Query().Get("include_deleted")) 153 onlyOrphaned, _ := strconv.ParseBool(r.URL.Query().Get("only_orphaned")) 154 155 var OwnerId string 156 if c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_READ_OTHERS_BOTS) { 157 // Get bots created by any user. 158 OwnerId = "" 159 } else if c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_READ_BOTS) { 160 // Only get bots created by this user. 161 OwnerId = c.App.Session().UserId 162 } else { 163 c.SetPermissionError(model.PERMISSION_READ_BOTS) 164 return 165 } 166 167 bots, appErr := c.App.GetBots(&model.BotGetOptions{ 168 Page: c.Params.Page, 169 PerPage: c.Params.PerPage, 170 OwnerId: OwnerId, 171 IncludeDeleted: includeDeleted, 172 OnlyOrphaned: onlyOrphaned, 173 }) 174 if appErr != nil { 175 c.Err = appErr 176 return 177 } 178 179 if c.HandleEtag(bots.Etag(), "Get Bots", w, r) { 180 return 181 } 182 183 w.Write(bots.ToJson()) 184 } 185 186 func disableBot(c *Context, w http.ResponseWriter, r *http.Request) { 187 updateBotActive(c, w, r, false) 188 } 189 190 func enableBot(c *Context, w http.ResponseWriter, r *http.Request) { 191 updateBotActive(c, w, r, true) 192 } 193 194 func updateBotActive(c *Context, w http.ResponseWriter, r *http.Request, active bool) { 195 c.RequireBotUserId() 196 if c.Err != nil { 197 return 198 } 199 botUserId := c.Params.BotUserId 200 201 auditRec := c.MakeAuditRecord("updateBotActive", audit.Fail) 202 defer c.LogAuditRec(auditRec) 203 auditRec.AddMeta("bot_id", botUserId) 204 auditRec.AddMeta("enable", active) 205 206 if err := c.App.SessionHasPermissionToManageBot(*c.App.Session(), botUserId); err != nil { 207 c.Err = err 208 return 209 } 210 211 bot, err := c.App.UpdateBotActive(botUserId, active) 212 if err != nil { 213 c.Err = err 214 return 215 } 216 217 auditRec.Success() 218 auditRec.AddMeta("bot", bot) 219 220 w.Write(bot.ToJson()) 221 } 222 223 func assignBot(c *Context, w http.ResponseWriter, r *http.Request) { 224 c.RequireUserId() 225 c.RequireBotUserId() 226 if c.Err != nil { 227 return 228 } 229 botUserId := c.Params.BotUserId 230 userId := c.Params.UserId 231 232 auditRec := c.MakeAuditRecord("assignBot", audit.Fail) 233 defer c.LogAuditRec(auditRec) 234 auditRec.AddMeta("bot_id", botUserId) 235 auditRec.AddMeta("assign_user_id", userId) 236 237 if err := c.App.SessionHasPermissionToManageBot(*c.App.Session(), botUserId); err != nil { 238 c.Err = err 239 return 240 } 241 242 if user, err := c.App.GetUser(userId); err == nil { 243 if user.IsBot { 244 c.SetPermissionError(model.PERMISSION_ASSIGN_BOT) 245 return 246 } 247 } 248 249 bot, err := c.App.UpdateBotOwner(botUserId, userId) 250 if err != nil { 251 c.Err = err 252 return 253 } 254 255 auditRec.Success() 256 auditRec.AddMeta("bot", bot) 257 258 w.Write(bot.ToJson()) 259 } 260 261 func getBotIconImage(c *Context, w http.ResponseWriter, r *http.Request) { 262 c.RequireBotUserId() 263 if c.Err != nil { 264 return 265 } 266 botUserId := c.Params.BotUserId 267 268 canSee, err := c.App.UserCanSeeOtherUser(c.App.Session().UserId, botUserId) 269 if err != nil { 270 c.Err = err 271 return 272 } 273 274 if !canSee { 275 c.SetPermissionError(model.PERMISSION_VIEW_MEMBERS) 276 return 277 } 278 279 img, err := c.App.GetBotIconImage(botUserId) 280 if err != nil { 281 c.Err = err 282 return 283 } 284 285 user, err := c.App.GetUser(botUserId) 286 if err != nil { 287 c.Err = err 288 return 289 } 290 291 etag := strconv.FormatInt(user.LastPictureUpdate, 10) 292 if c.HandleEtag(etag, "Get Icon Image", w, r) { 293 return 294 } 295 296 w.Header().Set("Cache-Control", fmt.Sprintf("max-age=%v, public", 24*60*60)) // 24 hrs 297 w.Header().Set(model.HEADER_ETAG_SERVER, etag) 298 w.Header().Set("Content-Type", "image/svg+xml") 299 w.Write(img) 300 } 301 302 func setBotIconImage(c *Context, w http.ResponseWriter, r *http.Request) { 303 defer io.Copy(ioutil.Discard, r.Body) 304 305 c.RequireBotUserId() 306 if c.Err != nil { 307 return 308 } 309 botUserId := c.Params.BotUserId 310 311 auditRec := c.MakeAuditRecord("setBotIconImage", audit.Fail) 312 defer c.LogAuditRec(auditRec) 313 auditRec.AddMeta("bot_id", botUserId) 314 315 if err := c.App.SessionHasPermissionToManageBot(*c.App.Session(), botUserId); err != nil { 316 c.Err = err 317 return 318 } 319 320 if r.ContentLength > *c.App.Config().FileSettings.MaxFileSize { 321 c.Err = model.NewAppError("setBotIconImage", "api.bot.set_bot_icon_image.too_large.app_error", nil, "", http.StatusRequestEntityTooLarge) 322 return 323 } 324 325 if err := r.ParseMultipartForm(*c.App.Config().FileSettings.MaxFileSize); err != nil { 326 c.Err = model.NewAppError("setBotIconImage", "api.bot.set_bot_icon_image.parse.app_error", nil, err.Error(), http.StatusInternalServerError) 327 return 328 } 329 330 m := r.MultipartForm 331 imageArray, ok := m.File["image"] 332 if !ok { 333 c.Err = model.NewAppError("setBotIconImage", "api.bot.set_bot_icon_image.no_file.app_error", nil, "", http.StatusBadRequest) 334 return 335 } 336 337 if len(imageArray) <= 0 { 338 c.Err = model.NewAppError("setBotIconImage", "api.bot.set_bot_icon_image.array.app_error", nil, "", http.StatusBadRequest) 339 return 340 } 341 342 imageData := imageArray[0] 343 if err := c.App.SetBotIconImageFromMultiPartFile(botUserId, imageData); err != nil { 344 c.Err = err 345 return 346 } 347 348 auditRec.Success() 349 c.LogAudit("") 350 351 ReturnStatusOK(w) 352 } 353 354 func deleteBotIconImage(c *Context, w http.ResponseWriter, r *http.Request) { 355 defer io.Copy(ioutil.Discard, r.Body) 356 357 c.RequireBotUserId() 358 if c.Err != nil { 359 return 360 } 361 botUserId := c.Params.BotUserId 362 363 auditRec := c.MakeAuditRecord("deleteBotIconImage", audit.Fail) 364 defer c.LogAuditRec(auditRec) 365 auditRec.AddMeta("bot_id", botUserId) 366 367 if err := c.App.SessionHasPermissionToManageBot(*c.App.Session(), botUserId); err != nil { 368 c.Err = err 369 return 370 } 371 372 if err := c.App.DeleteBotIconImage(botUserId); err != nil { 373 c.Err = err 374 return 375 } 376 377 auditRec.Success() 378 c.LogAudit("") 379 380 ReturnStatusOK(w) 381 } 382 383 func convertBotToUser(c *Context, w http.ResponseWriter, r *http.Request) { 384 c.RequireBotUserId() 385 if c.Err != nil { 386 return 387 } 388 389 bot, err := c.App.GetBot(c.Params.BotUserId, false) 390 if err != nil { 391 c.Err = err 392 return 393 } 394 395 userPatch := model.UserPatchFromJson(r.Body) 396 if userPatch == nil || userPatch.Password == nil || *userPatch.Password == "" { 397 c.SetInvalidParam("userPatch") 398 return 399 } 400 401 systemAdmin, _ := strconv.ParseBool(r.URL.Query().Get("set_system_admin")) 402 403 auditRec := c.MakeAuditRecord("convertBotToUser", audit.Fail) 404 defer c.LogAuditRec(auditRec) 405 auditRec.AddMeta("bot", bot) 406 auditRec.AddMeta("userPatch", userPatch) 407 auditRec.AddMeta("set_system_admin", systemAdmin) 408 409 if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) { 410 c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM) 411 return 412 } 413 414 user, err := c.App.ConvertBotToUser(bot, userPatch, systemAdmin) 415 if err != nil { 416 c.Err = err 417 return 418 } 419 420 auditRec.Success() 421 auditRec.AddMeta("convertedTo", user) 422 423 w.Write([]byte(user.ToJson())) 424 }