func (me *msgProvider) DoCommand(c *Context, args *model.CommandArgs, message string) *model.CommandResponse { splitMessage := strings.SplitN(message, " ", 2) parsedMessage := "" targetUsername := "" if len(splitMessage) > 1 { parsedMessage = strings.SplitN(message, " ", 2)[1] } targetUsername = strings.SplitN(message, " ", 2)[0] targetUsername = strings.TrimPrefix(targetUsername, "@") var userProfile *model.User if result := <-app.Srv.Store.User().GetByUsername(targetUsername); result.Err != nil { c.Err = result.Err return &model.CommandResponse{Text: c.T("api.command_msg.missing.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} } else { userProfile = result.Data.(*model.User) } if userProfile.Id == c.Session.UserId { return &model.CommandResponse{Text: c.T("api.command_msg.missing.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} } // Find the channel based on this user channelName := model.GetDMNameFromIds(c.Session.UserId, userProfile.Id) targetChannelId := "" if channel := <-app.Srv.Store.Channel().GetByName(c.TeamId, channelName); channel.Err != nil { if channel.Err.Id == "store.sql_channel.get_by_name.missing.app_error" { if directChannel, err := app.CreateDirectChannel(c.Session.UserId, userProfile.Id); err != nil { c.Err = err return &model.CommandResponse{Text: c.T("api.command_msg.dm_fail.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} } else { targetChannelId = directChannel.Id } } else { c.Err = channel.Err return &model.CommandResponse{Text: c.T("api.command_msg.dm_fail.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} } } else { targetChannelId = channel.Data.(*model.Channel).Id } app.MakeDirectChannelVisible(targetChannelId) if len(parsedMessage) > 0 { post := &model.Post{} post.Message = parsedMessage post.ChannelId = targetChannelId post.UserId = c.Session.UserId if _, err := app.CreatePost(post, c.TeamId, true); err != nil { return &model.CommandResponse{Text: c.T("api.command_msg.fail.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} } } return &model.CommandResponse{GotoLocation: c.GetTeamURL() + "/channels/" + channelName, Text: "", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} }
func (me *EchoProvider) DoCommand(c *Context, args *model.CommandArgs, message string) *model.CommandResponse { if len(message) == 0 { return &model.CommandResponse{Text: c.T("api.command_echo.message.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} } maxThreads := 100 delay := 0 if endMsg := strings.LastIndex(message, "\""); string(message[0]) == "\"" && endMsg > 1 { if checkDelay, err := strconv.Atoi(strings.Trim(message[endMsg:], " \"")); err == nil { delay = checkDelay } message = message[1:endMsg] } else if strings.Index(message, " ") > -1 { delayIdx := strings.LastIndex(message, " ") delayStr := strings.Trim(message[delayIdx:], " ") if checkDelay, err := strconv.Atoi(delayStr); err == nil { delay = checkDelay message = message[:delayIdx] } } if delay > 10000 { return &model.CommandResponse{Text: c.T("api.command_echo.delay.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} } if echoSem == nil { // We want one additional thread allowed so we never reach channel lockup echoSem = make(chan bool, maxThreads+1) } if len(echoSem) >= maxThreads { return &model.CommandResponse{Text: c.T("api.command_echo.high_volume.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} } echoSem <- true go func() { defer func() { <-echoSem }() post := &model.Post{} post.ChannelId = args.ChannelId post.RootId = args.RootId post.ParentId = args.ParentId post.Message = message post.UserId = c.Session.UserId time.Sleep(time.Duration(delay) * time.Second) if _, err := app.CreatePost(post, c.TeamId, true); err != nil { l4g.Error(c.T("api.command_echo.create.app_error"), err) } }() return &model.CommandResponse{} }
func createPost(c *Context, w http.ResponseWriter, r *http.Request) { post := model.PostFromJson(r.Body) if post == nil { c.SetInvalidParam("createPost", "post") return } post.UserId = c.Session.UserId cchan := app.Srv.Store.Channel().Get(post.ChannelId, true) if !HasPermissionToChannelContext(c, post.ChannelId, model.PERMISSION_CREATE_POST) { return } // Check that channel has not been deleted var channel *model.Channel if result := <-cchan; result.Err != nil { c.SetInvalidParam("createPost", "post.channelId") return } else { channel = result.Data.(*model.Channel) } if channel.DeleteAt != 0 { c.Err = model.NewLocAppError("createPost", "api.post.create_post.can_not_post_to_deleted.error", nil, "") c.Err.StatusCode = http.StatusBadRequest return } if post.CreateAt != 0 && !HasPermissionToContext(c, model.PERMISSION_MANAGE_SYSTEM) { post.CreateAt = 0 } if rp, err := app.CreatePost(post, c.TeamId, true); err != nil { c.Err = err if c.Err.Id == "api.post.create_post.root_id.app_error" || c.Err.Id == "api.post.create_post.channel_root_id.app_error" || c.Err.Id == "api.post.create_post.parent_id.app_error" { c.Err.StatusCode = http.StatusBadRequest } return } else { // Update the LastViewAt only if the post does not have from_webhook prop set (eg. Zapier app) if _, ok := post.Props["from_webhook"]; !ok { if result := <-app.Srv.Store.Channel().UpdateLastViewedAt([]string{post.ChannelId}, c.Session.UserId); result.Err != nil { l4g.Error(utils.T("api.post.create_post.last_viewed.error"), post.ChannelId, c.Session.UserId, result.Err) } } w.Write([]byte(rp.ToJson())) } }
func (me *LoadTestProvider) UrlCommand(c *Context, channelId string, message string) *model.CommandResponse { url := strings.TrimSpace(strings.TrimPrefix(message, "url")) if len(url) == 0 { return &model.CommandResponse{Text: "Command must contain a url", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} } // provide a shortcut to easily access tests stored in doc/developer/tests if !strings.HasPrefix(url, "http") { url = "https://raw.githubusercontent.com/mattermost/platform/master/tests/" + url if path.Ext(url) == "" { url += ".md" } } var contents io.ReadCloser if r, err := http.Get(url); err != nil { return &model.CommandResponse{Text: "Unable to get file", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} } else if r.StatusCode > 400 { return &model.CommandResponse{Text: "Unable to get file", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} } else { contents = r.Body } bytes := make([]byte, 4000) // break contents into 4000 byte posts for { length, err := contents.Read(bytes) if err != nil && err != io.EOF { return &model.CommandResponse{Text: "Encountered error reading file", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} } if length == 0 { break } post := &model.Post{} post.Message = string(bytes[:length]) post.ChannelId = channelId post.UserId = c.Session.UserId if _, err := app.CreatePost(post, c.TeamId, false); err != nil { return &model.CommandResponse{Text: "Unable to create post", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} } } return &model.CommandResponse{Text: "Loaded data", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} }
func (me *LoadTestProvider) JsonCommand(c *Context, channelId string, message string) *model.CommandResponse { url := strings.TrimSpace(strings.TrimPrefix(message, "json")) if len(url) == 0 { return &model.CommandResponse{Text: "Command must contain a url", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} } // provide a shortcut to easily access tests stored in doc/developer/tests if !strings.HasPrefix(url, "http") { url = "https://raw.githubusercontent.com/mattermost/platform/master/tests/" + url if path.Ext(url) == "" { url += ".json" } } var contents io.ReadCloser if r, err := http.Get(url); err != nil { return &model.CommandResponse{Text: "Unable to get file", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} } else if r.StatusCode > 400 { return &model.CommandResponse{Text: "Unable to get file", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} } else { contents = r.Body } post := model.PostFromJson(contents) post.ChannelId = channelId post.UserId = c.Session.UserId if post.Message == "" { post.Message = message } if _, err := app.CreatePost(post, c.TeamId, false); err != nil { return &model.CommandResponse{Text: "Unable to create post", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} } return &model.CommandResponse{Text: "Loaded data", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} }
func deleteChannel(c *Context, w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) id := params["channel_id"] sc := app.Srv.Store.Channel().Get(id, true) scm := app.Srv.Store.Channel().GetMember(id, c.Session.UserId) cmc := app.Srv.Store.Channel().GetMemberCount(id, false) uc := app.Srv.Store.User().Get(c.Session.UserId) ihc := app.Srv.Store.Webhook().GetIncomingByChannel(id) ohc := app.Srv.Store.Webhook().GetOutgoingByChannel(id) if cresult := <-sc; cresult.Err != nil { c.Err = cresult.Err return } else if uresult := <-uc; uresult.Err != nil { c.Err = cresult.Err return } else if scmresult := <-scm; scmresult.Err != nil { c.Err = scmresult.Err return } else if cmcresult := <-cmc; cmcresult.Err != nil { c.Err = cmcresult.Err return } else if ihcresult := <-ihc; ihcresult.Err != nil { c.Err = ihcresult.Err return } else if ohcresult := <-ohc; ohcresult.Err != nil { c.Err = ohcresult.Err return } else { channel := cresult.Data.(*model.Channel) memberCount := cmcresult.Data.(int64) user := uresult.Data.(*model.User) incomingHooks := ihcresult.Data.([]*model.IncomingWebhook) outgoingHooks := ohcresult.Data.([]*model.OutgoingWebhook) // Don't need to do anything with channel member, just wanted to confirm it exists // Allow delete if user is the only member left in channel if memberCount > 1 { if channel.Type == model.CHANNEL_OPEN && !HasPermissionToChannelContext(c, channel.Id, model.PERMISSION_DELETE_PUBLIC_CHANNEL) { return } if channel.Type == model.CHANNEL_PRIVATE && !HasPermissionToChannelContext(c, channel.Id, model.PERMISSION_DELETE_PRIVATE_CHANNEL) { return } } if channel.DeleteAt > 0 { c.Err = model.NewLocAppError("deleteChannel", "api.channel.delete_channel.deleted.app_error", nil, "") c.Err.StatusCode = http.StatusBadRequest return } if channel.Name == model.DEFAULT_CHANNEL { c.Err = model.NewLocAppError("deleteChannel", "api.channel.delete_channel.cannot.app_error", map[string]interface{}{"Channel": model.DEFAULT_CHANNEL}, "") c.Err.StatusCode = http.StatusBadRequest return } post := &model.Post{ ChannelId: channel.Id, Message: fmt.Sprintf(c.T("api.channel.delete_channel.archived"), user.Username), Type: model.POST_CHANNEL_DELETED, UserId: c.Session.UserId, } if _, err := app.CreatePost(post, c.TeamId, false); err != nil { l4g.Error(utils.T("api.channel.delete_channel.failed_post.error"), err) } now := model.GetMillis() for _, hook := range incomingHooks { if result := <-app.Srv.Store.Webhook().DeleteIncoming(hook.Id, now); result.Err != nil { l4g.Error(utils.T("api.channel.delete_channel.incoming_webhook.error"), hook.Id) } } for _, hook := range outgoingHooks { if result := <-app.Srv.Store.Webhook().DeleteOutgoing(hook.Id, now); result.Err != nil { l4g.Error(utils.T("api.channel.delete_channel.outgoing_webhook.error"), hook.Id) } } if dresult := <-app.Srv.Store.Channel().Delete(channel.Id, model.GetMillis()); dresult.Err != nil { c.Err = dresult.Err return } app.InvalidateCacheForChannel(channel.Id) c.LogAudit("name=" + channel.Name) message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_DELETED, c.TeamId, "", "", nil) message.Add("channel_id", channel.Id) app.Publish(message) result := make(map[string]string) result["id"] = channel.Id w.Write([]byte(model.MapToJson(result))) } }