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  }