bot.go 11 KB

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