From e9c6cc269b5c9fe82e5f38d63344a07365bccd6b Mon Sep 17 00:00:00 2001 From: Joram Wilander Date: Mon, 13 Mar 2017 09:23:16 -0400 Subject: Move command logic into app layer (#5617) --- api/auto_channels.go | 74 ------- api/auto_constants.go | 36 ---- api/auto_environment.go | 99 ---------- api/auto_posts.go | 103 ---------- api/auto_teams.go | 81 -------- api/auto_users.go | 110 ----------- api/command.go | 434 ++++++++++------------------------------ api/command_away.go | 43 ---- api/command_echo.go | 97 --------- api/command_expand_collapse.go | 87 -------- api/command_invite_people.go | 64 ------ api/command_join.go | 57 ------ api/command_loadtest.go | 439 ----------------------------------------- api/command_logout.go | 48 ----- api/command_me.go | 37 ---- api/command_msg.go | 95 --------- api/command_offline.go | 43 ---- api/command_online.go | 43 ---- api/command_shortcuts.go | 94 --------- api/command_shrug.go | 42 ---- 20 files changed, 100 insertions(+), 2026 deletions(-) delete mode 100644 api/auto_channels.go delete mode 100644 api/auto_constants.go delete mode 100644 api/auto_environment.go delete mode 100644 api/auto_posts.go delete mode 100644 api/auto_teams.go delete mode 100644 api/auto_users.go delete mode 100644 api/command_away.go delete mode 100644 api/command_echo.go delete mode 100644 api/command_expand_collapse.go delete mode 100644 api/command_invite_people.go delete mode 100644 api/command_join.go delete mode 100644 api/command_loadtest.go delete mode 100644 api/command_logout.go delete mode 100644 api/command_me.go delete mode 100644 api/command_msg.go delete mode 100644 api/command_offline.go delete mode 100644 api/command_online.go delete mode 100644 api/command_shortcuts.go delete mode 100644 api/command_shrug.go (limited to 'api') diff --git a/api/auto_channels.go b/api/auto_channels.go deleted file mode 100644 index 1d0f0e7d9..000000000 --- a/api/auto_channels.go +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -package api - -import ( - "github.com/mattermost/platform/model" - "github.com/mattermost/platform/utils" -) - -type AutoChannelCreator struct { - client *model.Client - team *model.Team - Fuzzy bool - DisplayNameLen utils.Range - DisplayNameCharset string - NameLen utils.Range - NameCharset string - ChannelType string -} - -func NewAutoChannelCreator(client *model.Client, team *model.Team) *AutoChannelCreator { - return &AutoChannelCreator{ - client: client, - team: team, - Fuzzy: false, - DisplayNameLen: CHANNEL_DISPLAY_NAME_LEN, - DisplayNameCharset: utils.ALPHANUMERIC, - NameLen: CHANNEL_NAME_LEN, - NameCharset: utils.LOWERCASE, - ChannelType: CHANNEL_TYPE, - } -} - -func (cfg *AutoChannelCreator) createRandomChannel() (*model.Channel, bool) { - var displayName string - if cfg.Fuzzy { - displayName = utils.FuzzName() - } else { - displayName = utils.RandomName(cfg.NameLen, cfg.NameCharset) - } - name := utils.RandomName(cfg.NameLen, cfg.NameCharset) - - channel := &model.Channel{ - TeamId: cfg.team.Id, - DisplayName: displayName, - Name: name, - Type: cfg.ChannelType} - - println(cfg.client.GetTeamRoute()) - result, err := cfg.client.CreateChannel(channel) - if err != nil { - err.Translate(utils.T) - println(err.Error()) - println(err.DetailedError) - return nil, false - } - return result.Data.(*model.Channel), true -} - -func (cfg *AutoChannelCreator) CreateTestChannels(num utils.Range) ([]*model.Channel, bool) { - numChannels := utils.RandIntFromRange(num) - channels := make([]*model.Channel, numChannels) - - for i := 0; i < numChannels; i++ { - var err bool - channels[i], err = cfg.createRandomChannel() - if err != true { - return channels, false - } - } - - return channels, true -} diff --git a/api/auto_constants.go b/api/auto_constants.go deleted file mode 100644 index a10ae99f2..000000000 --- a/api/auto_constants.go +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -package api - -import ( - "github.com/mattermost/platform/model" - "github.com/mattermost/platform/utils" -) - -const ( - USER_PASSWORD = "passwd" - CHANNEL_TYPE = model.CHANNEL_OPEN - FUZZ_USER_EMAIL_PREFIX_LEN = 10 - BTEST_TEAM_DISPLAY_NAME = "TestTeam" - BTEST_TEAM_NAME = "z-z-testdomaina" - BTEST_TEAM_EMAIL = "test@nowhere.com" - BTEST_TEAM_TYPE = model.TEAM_OPEN - BTEST_USER_NAME = "Mr. Testing Tester" - BTEST_USER_EMAIL = "success+ttester@simulator.amazonses.com" - BTEST_USER_PASSWORD = "passwd" -) - -var ( - TEAM_NAME_LEN = utils.Range{Begin: 10, End: 20} - TEAM_DOMAIN_NAME_LEN = utils.Range{Begin: 10, End: 20} - TEAM_EMAIL_LEN = utils.Range{Begin: 15, End: 30} - USER_NAME_LEN = utils.Range{Begin: 5, End: 20} - USER_EMAIL_LEN = utils.Range{Begin: 15, End: 30} - CHANNEL_DISPLAY_NAME_LEN = utils.Range{Begin: 10, End: 20} - CHANNEL_NAME_LEN = utils.Range{Begin: 5, End: 20} - POST_MESSAGE_LEN = utils.Range{Begin: 100, End: 400} - POST_HASHTAGS_NUM = utils.Range{Begin: 5, End: 10} - POST_MENTIONS_NUM = utils.Range{Begin: 0, End: 3} - TEST_IMAGE_FILENAMES = []string{"test.png", "testjpg.jpg", "testgif.gif"} -) diff --git a/api/auto_environment.go b/api/auto_environment.go deleted file mode 100644 index 6c7bc2d0a..000000000 --- a/api/auto_environment.go +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -package api - -import ( - "github.com/mattermost/platform/model" - "github.com/mattermost/platform/utils" - "math/rand" - "time" -) - -type TestEnvironment struct { - Teams []*model.Team - Environments []TeamEnvironment -} - -func CreateTestEnvironmentWithTeams(client *model.Client, rangeTeams utils.Range, rangeChannels utils.Range, rangeUsers utils.Range, rangePosts utils.Range, fuzzy bool) (TestEnvironment, bool) { - rand.Seed(time.Now().UTC().UnixNano()) - - teamCreator := NewAutoTeamCreator(client) - teamCreator.Fuzzy = fuzzy - teams, err := teamCreator.CreateTestTeams(rangeTeams) - if err != true { - return TestEnvironment{}, false - } - - environment := TestEnvironment{teams, make([]TeamEnvironment, len(teams))} - - for i, team := range teams { - userCreator := NewAutoUserCreator(client, team) - userCreator.Fuzzy = fuzzy - randomUser, err := userCreator.createRandomUser() - if err != true { - return TestEnvironment{}, false - } - client.LoginById(randomUser.Id, USER_PASSWORD) - client.SetTeamId(team.Id) - teamEnvironment, err := CreateTestEnvironmentInTeam(client, team, rangeChannels, rangeUsers, rangePosts, fuzzy) - if err != true { - return TestEnvironment{}, false - } - environment.Environments[i] = teamEnvironment - } - - return environment, true -} - -func CreateTestEnvironmentInTeam(client *model.Client, team *model.Team, rangeChannels utils.Range, rangeUsers utils.Range, rangePosts utils.Range, fuzzy bool) (TeamEnvironment, bool) { - rand.Seed(time.Now().UTC().UnixNano()) - - // We need to create at least one user - if rangeUsers.Begin <= 0 { - rangeUsers.Begin = 1 - } - - userCreator := NewAutoUserCreator(client, team) - userCreator.Fuzzy = fuzzy - users, err := userCreator.CreateTestUsers(rangeUsers) - if err != true { - return TeamEnvironment{}, false - } - usernames := make([]string, len(users)) - for i, user := range users { - usernames[i] = user.Username - } - - channelCreator := NewAutoChannelCreator(client, team) - channelCreator.Fuzzy = fuzzy - channels, err := channelCreator.CreateTestChannels(rangeChannels) - - // Have every user join every channel - for _, user := range users { - for _, channel := range channels { - client.LoginById(user.Id, USER_PASSWORD) - client.JoinChannel(channel.Id) - } - } - - if err != true { - return TeamEnvironment{}, false - } - - numPosts := utils.RandIntFromRange(rangePosts) - numImages := utils.RandIntFromRange(rangePosts) / 4 - for j := 0; j < numPosts; j++ { - user := users[utils.RandIntFromRange(utils.Range{Begin: 0, End: len(users) - 1})] - client.LoginById(user.Id, USER_PASSWORD) - for i, channel := range channels { - postCreator := NewAutoPostCreator(client, channel.Id) - postCreator.HasImage = i < numImages - postCreator.Users = usernames - postCreator.Fuzzy = fuzzy - postCreator.CreateRandomPost() - } - } - - return TeamEnvironment{users, channels}, true -} diff --git a/api/auto_posts.go b/api/auto_posts.go deleted file mode 100644 index bb20aadae..000000000 --- a/api/auto_posts.go +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -package api - -import ( - "bytes" - "github.com/mattermost/platform/model" - "github.com/mattermost/platform/utils" - "io" - "os" -) - -type AutoPostCreator struct { - client *model.Client - channelid string - Fuzzy bool - TextLength utils.Range - HasImage bool - ImageFilenames []string - Users []string - Mentions utils.Range - Tags utils.Range -} - -// Automatic poster used for testing -func NewAutoPostCreator(client *model.Client, channelid string) *AutoPostCreator { - return &AutoPostCreator{ - client: client, - channelid: channelid, - Fuzzy: false, - TextLength: utils.Range{Begin: 100, End: 200}, - HasImage: false, - ImageFilenames: TEST_IMAGE_FILENAMES, - Users: []string{}, - Mentions: utils.Range{Begin: 0, End: 5}, - Tags: utils.Range{Begin: 0, End: 7}, - } -} - -func (cfg *AutoPostCreator) UploadTestFile() ([]string, bool) { - filename := cfg.ImageFilenames[utils.RandIntFromRange(utils.Range{Begin: 0, End: len(cfg.ImageFilenames) - 1})] - - path := utils.FindDir("web/static/images") - file, err := os.Open(path + "/" + filename) - defer file.Close() - - data := &bytes.Buffer{} - _, err = io.Copy(data, file) - if err != nil { - return nil, false - } - - resp, appErr := cfg.client.UploadPostAttachment(data.Bytes(), cfg.channelid, filename) - if appErr != nil { - return nil, false - } - - return []string{resp.FileInfos[0].Id}, true -} - -func (cfg *AutoPostCreator) CreateRandomPost() (*model.Post, bool) { - var fileIds []string - if cfg.HasImage { - var err1 bool - fileIds, err1 = cfg.UploadTestFile() - if err1 == false { - return nil, false - } - } - - var postText string - if cfg.Fuzzy { - postText = utils.FuzzPost() - } else { - postText = utils.RandomText(cfg.TextLength, cfg.Tags, cfg.Mentions, cfg.Users) - } - - post := &model.Post{ - ChannelId: cfg.channelid, - Message: postText, - FileIds: fileIds} - result, err2 := cfg.client.CreatePost(post) - if err2 != nil { - return nil, false - } - return result.Data.(*model.Post), true -} - -func (cfg *AutoPostCreator) CreateTestPosts(rangePosts utils.Range) ([]*model.Post, bool) { - numPosts := utils.RandIntFromRange(rangePosts) - posts := make([]*model.Post, numPosts) - - for i := 0; i < numPosts; i++ { - var err bool - posts[i], err = cfg.CreateRandomPost() - if err != true { - return posts, false - } - } - - return posts, true -} diff --git a/api/auto_teams.go b/api/auto_teams.go deleted file mode 100644 index b2e1ace85..000000000 --- a/api/auto_teams.go +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -package api - -import ( - "github.com/mattermost/platform/model" - "github.com/mattermost/platform/utils" -) - -type TeamEnvironment struct { - Users []*model.User - Channels []*model.Channel -} - -type AutoTeamCreator struct { - client *model.Client - Fuzzy bool - NameLength utils.Range - NameCharset string - DomainLength utils.Range - DomainCharset string - EmailLength utils.Range - EmailCharset string -} - -func NewAutoTeamCreator(client *model.Client) *AutoTeamCreator { - return &AutoTeamCreator{ - client: client, - Fuzzy: false, - NameLength: TEAM_NAME_LEN, - NameCharset: utils.LOWERCASE, - DomainLength: TEAM_DOMAIN_NAME_LEN, - DomainCharset: utils.LOWERCASE, - EmailLength: TEAM_EMAIL_LEN, - EmailCharset: utils.LOWERCASE, - } -} - -func (cfg *AutoTeamCreator) createRandomTeam() (*model.Team, bool) { - var teamEmail string - var teamDisplayName string - var teamName string - if cfg.Fuzzy { - teamEmail = "success+" + model.NewId() + "simulator.amazonses.com" - teamDisplayName = utils.FuzzName() - teamName = utils.FuzzName() - } else { - teamEmail = "success+" + model.NewId() + "simulator.amazonses.com" - teamDisplayName = utils.RandomName(cfg.NameLength, cfg.NameCharset) - teamName = utils.RandomName(cfg.NameLength, cfg.NameCharset) + model.NewId() - } - team := &model.Team{ - DisplayName: teamDisplayName, - Name: teamName, - Email: teamEmail, - Type: model.TEAM_OPEN, - } - - result, err := cfg.client.CreateTeam(team) - if err != nil { - return nil, false - } - createdTeam := result.Data.(*model.Team) - return createdTeam, true -} - -func (cfg *AutoTeamCreator) CreateTestTeams(num utils.Range) ([]*model.Team, bool) { - numTeams := utils.RandIntFromRange(num) - teams := make([]*model.Team, numTeams) - - for i := 0; i < numTeams; i++ { - var err bool - teams[i], err = cfg.createRandomTeam() - if err != true { - return teams, false - } - } - - return teams, true -} diff --git a/api/auto_users.go b/api/auto_users.go deleted file mode 100644 index d8cd8d3a3..000000000 --- a/api/auto_users.go +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -package api - -import ( - "github.com/mattermost/platform/app" - "github.com/mattermost/platform/model" - "github.com/mattermost/platform/store" - "github.com/mattermost/platform/utils" - - l4g "github.com/alecthomas/log4go" -) - -type AutoUserCreator struct { - client *model.Client - team *model.Team - EmailLength utils.Range - EmailCharset string - NameLength utils.Range - NameCharset string - Fuzzy bool -} - -func NewAutoUserCreator(client *model.Client, team *model.Team) *AutoUserCreator { - return &AutoUserCreator{ - client: client, - team: team, - EmailLength: USER_EMAIL_LEN, - EmailCharset: utils.LOWERCASE, - NameLength: USER_NAME_LEN, - NameCharset: utils.LOWERCASE, - Fuzzy: false, - } -} - -// Basic test team and user so you always know one -func CreateBasicUser(client *model.Client) *model.AppError { - result, _ := client.FindTeamByName(BTEST_TEAM_NAME) - if result.Data.(bool) == false { - newteam := &model.Team{DisplayName: BTEST_TEAM_DISPLAY_NAME, Name: BTEST_TEAM_NAME, Email: BTEST_TEAM_EMAIL, Type: BTEST_TEAM_TYPE} - result, err := client.CreateTeam(newteam) - if err != nil { - return err - } - basicteam := result.Data.(*model.Team) - newuser := &model.User{Email: BTEST_USER_EMAIL, Nickname: BTEST_USER_NAME, Password: BTEST_USER_PASSWORD} - result, err = client.CreateUser(newuser, "") - if err != nil { - return err - } - ruser := result.Data.(*model.User) - store.Must(app.Srv.Store.User().VerifyEmail(ruser.Id)) - store.Must(app.Srv.Store.Team().SaveMember(&model.TeamMember{TeamId: basicteam.Id, UserId: ruser.Id})) - } - return nil -} - -func (cfg *AutoUserCreator) createRandomUser() (*model.User, bool) { - var userEmail string - var userName string - if cfg.Fuzzy { - userEmail = "success+" + model.NewId() + "simulator.amazonses.com" - userName = utils.FuzzName() - } else { - userEmail = "success+" + model.NewId() + "simulator.amazonses.com" - userName = utils.RandomName(cfg.NameLength, cfg.NameCharset) - } - - user := &model.User{ - Email: userEmail, - Nickname: userName, - Password: USER_PASSWORD} - - result, err := cfg.client.CreateUserWithInvite(user, "", "", cfg.team.InviteId) - if err != nil { - err.Translate(utils.T) - l4g.Error(err.Error()) - return nil, false - } - - ruser := result.Data.(*model.User) - - status := &model.Status{UserId: ruser.Id, Status: model.STATUS_ONLINE, Manual: false, LastActivityAt: model.GetMillis(), ActiveChannel: ""} - if result := <-app.Srv.Store.Status().SaveOrUpdate(status); result.Err != nil { - result.Err.Translate(utils.T) - l4g.Error(result.Err.Error()) - return nil, false - } - - // We need to cheat to verify the user's email - store.Must(app.Srv.Store.User().VerifyEmail(ruser.Id)) - - return result.Data.(*model.User), true -} - -func (cfg *AutoUserCreator) CreateTestUsers(num utils.Range) ([]*model.User, bool) { - numUsers := utils.RandIntFromRange(num) - users := make([]*model.User, numUsers) - - for i := 0; i < numUsers; i++ { - var err bool - users[i], err = cfg.createRandomUser() - if err != true { - return users, false - } - } - - return users, true -} diff --git a/api/command.go b/api/command.go index c3a64702f..2248caf76 100644 --- a/api/command.go +++ b/api/command.go @@ -4,11 +4,8 @@ package api import ( - "crypto/tls" - "fmt" "io/ioutil" "net/http" - "net/url" "strings" l4g "github.com/alecthomas/log4go" @@ -18,27 +15,6 @@ import ( "github.com/mattermost/platform/utils" ) -type CommandProvider interface { - GetTrigger() string - GetCommand(c *Context) *model.Command - DoCommand(c *Context, args *model.CommandArgs, message string) *model.CommandResponse -} - -var commandProviders = make(map[string]CommandProvider) - -func RegisterCommandProvider(newProvider CommandProvider) { - commandProviders[newProvider.GetTrigger()] = newProvider -} - -func GetCommandProvider(name string) CommandProvider { - provider, ok := commandProviders[name] - if ok { - return provider - } - - return nil -} - func InitCommand() { l4g.Debug(utils.T("api.command.init.debug")) @@ -58,31 +34,10 @@ func InitCommand() { } func listCommands(c *Context, w http.ResponseWriter, r *http.Request) { - commands := make([]*model.Command, 0, 32) - seen := make(map[string]bool) - for _, value := range commandProviders { - cpy := *value.GetCommand(c) - if cpy.AutoComplete && !seen[cpy.Id] { - cpy.Sanitize() - seen[cpy.Trigger] = true - commands = append(commands, &cpy) - } - } - - if *utils.Cfg.ServiceSettings.EnableCommands { - if result := <-app.Srv.Store.Command().GetByTeam(c.TeamId); result.Err != nil { - c.Err = result.Err - return - } else { - teamCmds := result.Data.([]*model.Command) - for _, cmd := range teamCmds { - if cmd.AutoComplete && !seen[cmd.Id] { - cmd.Sanitize() - seen[cmd.Trigger] = true - commands = append(commands, cmd) - } - } - } + commands, err := app.ListCommands(c.TeamId, c.T) + if err != nil { + c.Err = err + return } w.Write([]byte(model.CommandListToJson(commands))) @@ -90,9 +45,13 @@ func listCommands(c *Context, w http.ResponseWriter, r *http.Request) { func executeCommand(c *Context, w http.ResponseWriter, r *http.Request) { commandArgs := model.CommandArgsFromJson(r.Body) + if commandArgs == nil { + c.SetInvalidParam("executeCommand", "command_args") + return + } if len(commandArgs.Command) <= 1 || strings.Index(commandArgs.Command, "/") != 0 { - c.Err = model.NewLocAppError("executeCommand", "api.command.execute_command.start.app_error", nil, "") + c.Err = model.NewAppError("executeCommand", "api.command.execute_command.start.app_error", nil, "", http.StatusBadRequest) return } @@ -103,232 +62,50 @@ func executeCommand(c *Context, w http.ResponseWriter, r *http.Request) { } } - parts := strings.Split(commandArgs.Command, " ") - trigger := parts[0][1:] - trigger = strings.ToLower(trigger) - message := strings.Join(parts[1:], " ") - provider := GetCommandProvider(trigger) - - if provider != nil { - response := provider.DoCommand(c, commandArgs, message) - handleResponse(c, w, response, commandArgs, provider.GetCommand(c), true) - return - } else { - - if !*utils.Cfg.ServiceSettings.EnableCommands { - c.Err = model.NewLocAppError("executeCommand", "api.command.disabled.app_error", nil, "") - c.Err.StatusCode = http.StatusNotImplemented - return - } - - chanChan := app.Srv.Store.Channel().Get(commandArgs.ChannelId, true) - teamChan := app.Srv.Store.Team().Get(c.TeamId) - userChan := app.Srv.Store.User().Get(c.Session.UserId) - - if result := <-app.Srv.Store.Command().GetByTeam(c.TeamId); result.Err != nil { - c.Err = result.Err - return - } else { - - var team *model.Team - if tr := <-teamChan; tr.Err != nil { - c.Err = tr.Err - return - } else { - team = tr.Data.(*model.Team) - } - - var user *model.User - if ur := <-userChan; ur.Err != nil { - c.Err = ur.Err - return - } else { - user = ur.Data.(*model.User) - } - - var channel *model.Channel - if cr := <-chanChan; cr.Err != nil { - c.Err = cr.Err - return - } else { - channel = cr.Data.(*model.Channel) - } - - teamCmds := result.Data.([]*model.Command) - for _, cmd := range teamCmds { - if trigger == cmd.Trigger { - l4g.Debug(fmt.Sprintf(utils.T("api.command.execute_command.debug"), trigger, c.Session.UserId)) - - p := url.Values{} - p.Set("token", cmd.Token) - - p.Set("team_id", cmd.TeamId) - p.Set("team_domain", team.Name) - - p.Set("channel_id", commandArgs.ChannelId) - p.Set("channel_name", channel.Name) - - p.Set("user_id", c.Session.UserId) - p.Set("user_name", user.Username) - - p.Set("command", "/"+trigger) - p.Set("text", message) - p.Set("response_url", "not supported yet") - - method := "POST" - if cmd.Method == model.COMMAND_METHOD_GET { - method = "GET" - } - - tr := &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: *utils.Cfg.ServiceSettings.EnableInsecureOutgoingConnections}, - } - client := &http.Client{Transport: tr} - - req, _ := http.NewRequest(method, cmd.URL, strings.NewReader(p.Encode())) - req.Header.Set("Accept", "application/json") - if cmd.Method == model.COMMAND_METHOD_POST { - req.Header.Set("Content-Type", "application/x-www-form-urlencoded") - } - - if resp, err := client.Do(req); err != nil { - c.Err = model.NewLocAppError("command", "api.command.execute_command.failed.app_error", map[string]interface{}{"Trigger": trigger}, err.Error()) - } else { - if resp.StatusCode == http.StatusOK { - response := model.CommandResponseFromJson(resp.Body) - if response == nil { - c.Err = model.NewLocAppError("command", "api.command.execute_command.failed_empty.app_error", map[string]interface{}{"Trigger": trigger}, "") - } else { - handleResponse(c, w, response, commandArgs, cmd, false) - } - } else { - defer resp.Body.Close() - body, _ := ioutil.ReadAll(resp.Body) - c.Err = model.NewLocAppError("command", "api.command.execute_command.failed_resp.app_error", map[string]interface{}{"Trigger": trigger, "Status": resp.Status}, string(body)) - } - } - - return - } - } - - } - } - - c.Err = model.NewLocAppError("command", "api.command.execute_command.not_found.app_error", map[string]interface{}{"Trigger": trigger}, "") -} + commandArgs.TeamId = c.TeamId + commandArgs.UserId = c.Session.UserId + commandArgs.T = c.T + commandArgs.Session = c.Session + commandArgs.SiteURL = c.GetSiteURL() -func handleResponse(c *Context, w http.ResponseWriter, response *model.CommandResponse, commandArgs *model.CommandArgs, cmd *model.Command, builtIn bool) { - if c.Err != nil { + response, err := app.ExecuteCommand(commandArgs) + if err != nil { + c.Err = err return } - post := &model.Post{} - post.ChannelId = commandArgs.ChannelId - post.RootId = commandArgs.RootId - post.ParentId = commandArgs.ParentId - post.UserId = c.Session.UserId - - if !builtIn { - post.AddProp("from_webhook", "true") - } - - if utils.Cfg.ServiceSettings.EnablePostUsernameOverride { - if len(cmd.Username) != 0 { - post.AddProp("override_username", cmd.Username) - } else if len(response.Username) != 0 { - post.AddProp("override_username", response.Username) - } - } - - if utils.Cfg.ServiceSettings.EnablePostIconOverride { - if len(cmd.IconURL) != 0 { - post.AddProp("override_icon_url", cmd.IconURL) - } else if len(response.IconURL) != 0 { - post.AddProp("override_icon_url", response.IconURL) - } else { - post.AddProp("override_icon_url", "") - } - } - - if _, err := app.CreateCommandPost(post, c.TeamId, response); err != nil { - l4g.Error(err.Error()) - } - w.Write([]byte(response.ToJson())) } func createCommand(c *Context, w http.ResponseWriter, r *http.Request) { - if !*utils.Cfg.ServiceSettings.EnableCommands { - c.Err = model.NewLocAppError("createCommand", "api.command.disabled.app_error", nil, "") - c.Err.StatusCode = http.StatusNotImplemented - return - } + cmd := model.CommandFromJson(r.Body) - if !app.SessionHasPermissionToTeam(c.Session, c.TeamId, model.PERMISSION_MANAGE_SLASH_COMMANDS) { - c.Err = model.NewLocAppError("createCommand", "api.command.admin_only.app_error", nil, "") - c.Err.StatusCode = http.StatusForbidden + if cmd == nil { + c.SetInvalidParam("createCommand", "command") return } c.LogAudit("attempt") - cmd := model.CommandFromJson(r.Body) - - if cmd == nil { - c.SetInvalidParam("createCommand", "command") + if !app.SessionHasPermissionToTeam(c.Session, c.TeamId, model.PERMISSION_MANAGE_SLASH_COMMANDS) { + c.SetPermissionError(model.PERMISSION_MANAGE_SLASH_COMMANDS) return } - cmd.Trigger = strings.ToLower(cmd.Trigger) cmd.CreatorId = c.Session.UserId cmd.TeamId = c.TeamId - if result := <-app.Srv.Store.Command().GetByTeam(c.TeamId); result.Err != nil { - c.Err = result.Err + rcmd, err := app.CreateCommand(cmd) + if err != nil { + c.Err = err return - } else { - teamCmds := result.Data.([]*model.Command) - for _, existingCommand := range teamCmds { - if cmd.Trigger == existingCommand.Trigger { - c.Err = model.NewLocAppError("createCommand", "api.command.duplicate_trigger.app_error", nil, "") - return - } - } - for _, builtInProvider := range commandProviders { - builtInCommand := *builtInProvider.GetCommand(c) - if cmd.Trigger == builtInCommand.Trigger { - c.Err = model.NewLocAppError("createCommand", "api.command.duplicate_trigger.app_error", nil, "") - return - } - } } - if result := <-app.Srv.Store.Command().Save(cmd); result.Err != nil { - c.Err = result.Err - return - } else { - c.LogAudit("success") - rcmd := result.Data.(*model.Command) - w.Write([]byte(rcmd.ToJson())) - } + c.LogAudit("success") + w.Write([]byte(rcmd.ToJson())) } func updateCommand(c *Context, w http.ResponseWriter, r *http.Request) { - if !*utils.Cfg.ServiceSettings.EnableCommands { - c.Err = model.NewLocAppError("updateCommand", "api.command.disabled.app_error", nil, "") - c.Err.StatusCode = http.StatusNotImplemented - return - } - - if !app.SessionHasPermissionToTeam(c.Session, c.TeamId, model.PERMISSION_MANAGE_SLASH_COMMANDS) { - c.Err = model.NewLocAppError("updateCommand", "api.command.admin_only.app_error", nil, "") - c.Err.StatusCode = http.StatusForbidden - return - } - - c.LogAudit("attempt") - cmd := model.CommandFromJson(r.Body) if cmd == nil { @@ -336,80 +113,58 @@ func updateCommand(c *Context, w http.ResponseWriter, r *http.Request) { return } - cmd.Trigger = strings.ToLower(cmd.Trigger) + c.LogAudit("attempt") - var oldCmd *model.Command - if result := <-app.Srv.Store.Command().Get(cmd.Id); result.Err != nil { - c.Err = result.Err + oldCmd, err := app.GetCommand(cmd.Id) + if err != nil { + c.Err = err return - } else { - oldCmd = result.Data.(*model.Command) - - if c.Session.UserId != oldCmd.CreatorId && !app.SessionHasPermissionToTeam(c.Session, c.TeamId, model.PERMISSION_MANAGE_OTHERS_SLASH_COMMANDS) { - c.LogAudit("fail - inappropriate permissions") - c.Err = model.NewLocAppError("updateCommand", "api.command.update.app_error", nil, "user_id="+c.Session.UserId) - return - } - - if c.TeamId != oldCmd.TeamId { - c.Err = model.NewLocAppError("updateCommand", "api.command.team_mismatch.app_error", nil, "user_id="+c.Session.UserId) - return - } - - cmd.Id = oldCmd.Id - cmd.Token = oldCmd.Token - cmd.CreateAt = oldCmd.CreateAt - cmd.UpdateAt = model.GetMillis() - cmd.DeleteAt = oldCmd.DeleteAt - cmd.CreatorId = oldCmd.CreatorId - cmd.TeamId = oldCmd.TeamId } - if result := <-app.Srv.Store.Command().Update(cmd); result.Err != nil { - c.Err = result.Err + if c.TeamId != oldCmd.TeamId { + c.Err = model.NewAppError("updateCommand", "api.command.team_mismatch.app_error", nil, "user_id="+c.Session.UserId, http.StatusBadRequest) return - } else { - w.Write([]byte(result.Data.(*model.Command).ToJson())) } -} -func listTeamCommands(c *Context, w http.ResponseWriter, r *http.Request) { - if !*utils.Cfg.ServiceSettings.EnableCommands { - c.Err = model.NewLocAppError("listTeamCommands", "api.command.disabled.app_error", nil, "") - c.Err.StatusCode = http.StatusNotImplemented + if !app.SessionHasPermissionToTeam(c.Session, oldCmd.TeamId, model.PERMISSION_MANAGE_SLASH_COMMANDS) { + c.LogAudit("fail - inappropriate permissions") + c.SetPermissionError(model.PERMISSION_MANAGE_SLASH_COMMANDS) return } - if !app.SessionHasPermissionToTeam(c.Session, c.TeamId, model.PERMISSION_MANAGE_SLASH_COMMANDS) { - c.Err = model.NewLocAppError("listTeamCommands", "api.command.admin_only.app_error", nil, "") - c.Err.StatusCode = http.StatusForbidden + if c.Session.UserId != oldCmd.CreatorId && !app.SessionHasPermissionToTeam(c.Session, c.TeamId, model.PERMISSION_MANAGE_OTHERS_SLASH_COMMANDS) { + c.LogAudit("fail - inappropriate permissions") + c.SetPermissionError(model.PERMISSION_MANAGE_OTHERS_SLASH_COMMANDS) return } - if result := <-app.Srv.Store.Command().GetByTeam(c.TeamId); result.Err != nil { - c.Err = result.Err + rcmd, err := app.UpdateCommand(oldCmd, cmd) + if err != nil { + c.Err = err return - } else { - cmds := result.Data.([]*model.Command) - w.Write([]byte(model.CommandListToJson(cmds))) } + + c.LogAudit("success") + + w.Write([]byte(rcmd.ToJson())) } -func regenCommandToken(c *Context, w http.ResponseWriter, r *http.Request) { - if !*utils.Cfg.ServiceSettings.EnableCommands { - c.Err = model.NewLocAppError("regenCommandToken", "api.command.disabled.app_error", nil, "") - c.Err.StatusCode = http.StatusNotImplemented +func listTeamCommands(c *Context, w http.ResponseWriter, r *http.Request) { + if !app.SessionHasPermissionToTeam(c.Session, c.TeamId, model.PERMISSION_MANAGE_SLASH_COMMANDS) { + c.SetPermissionError(model.PERMISSION_MANAGE_SLASH_COMMANDS) return } - if !app.SessionHasPermissionToTeam(c.Session, c.TeamId, model.PERMISSION_MANAGE_SLASH_COMMANDS) { - c.Err = model.NewLocAppError("regenCommandToken", "api.command.admin_only.app_error", nil, "") - c.Err.StatusCode = http.StatusForbidden + cmds, err := app.ListTeamCommands(c.TeamId) + if err != nil { + c.Err = err return } - c.LogAudit("attempt") + w.Write([]byte(model.CommandListToJson(cmds))) +} +func regenCommandToken(c *Context, w http.ResponseWriter, r *http.Request) { props := model.MapFromJson(r.Body) id := props["id"] @@ -418,45 +173,41 @@ func regenCommandToken(c *Context, w http.ResponseWriter, r *http.Request) { return } - var cmd *model.Command - if result := <-app.Srv.Store.Command().Get(id); result.Err != nil { - c.Err = result.Err - return - } else { - cmd = result.Data.(*model.Command) + c.LogAudit("attempt") - if c.TeamId != cmd.TeamId || (c.Session.UserId != cmd.CreatorId && !app.SessionHasPermissionToTeam(c.Session, c.TeamId, model.PERMISSION_MANAGE_OTHERS_SLASH_COMMANDS)) { - c.LogAudit("fail - inappropriate permissions") - c.Err = model.NewLocAppError("regenToken", "api.command.regen.app_error", nil, "user_id="+c.Session.UserId) - return - } + cmd, err := app.GetCommand(id) + if err != nil { + c.Err = err + return } - cmd.Token = model.NewId() + if c.TeamId != cmd.TeamId { + c.Err = model.NewAppError("regenCommandToken", "api.command.team_mismatch.app_error", nil, "user_id="+c.Session.UserId, http.StatusBadRequest) + return + } - if result := <-app.Srv.Store.Command().Update(cmd); result.Err != nil { - c.Err = result.Err + if !app.SessionHasPermissionToTeam(c.Session, cmd.TeamId, model.PERMISSION_MANAGE_SLASH_COMMANDS) { + c.LogAudit("fail - inappropriate permissions") + c.SetPermissionError(model.PERMISSION_MANAGE_SLASH_COMMANDS) return - } else { - w.Write([]byte(result.Data.(*model.Command).ToJson())) } -} -func deleteCommand(c *Context, w http.ResponseWriter, r *http.Request) { - if !*utils.Cfg.ServiceSettings.EnableCommands { - c.Err = model.NewLocAppError("deleteCommand", "api.command.disabled.app_error", nil, "") - c.Err.StatusCode = http.StatusNotImplemented + if c.Session.UserId != cmd.CreatorId && !app.SessionHasPermissionToTeam(c.Session, cmd.TeamId, model.PERMISSION_MANAGE_OTHERS_SLASH_COMMANDS) { + c.LogAudit("fail - inappropriate permissions") + c.SetPermissionError(model.PERMISSION_MANAGE_OTHERS_SLASH_COMMANDS) return } - if !app.SessionHasPermissionToTeam(c.Session, c.TeamId, model.PERMISSION_MANAGE_SLASH_COMMANDS) { - c.Err = model.NewLocAppError("deleteCommand", "api.command.admin_only.app_error", nil, "") - c.Err.StatusCode = http.StatusForbidden + rcmd, err := app.RegenCommandToken(cmd) + if err != nil { + c.Err = err return } - c.LogAudit("attempt") + w.Write([]byte(rcmd.ToJson())) +} +func deleteCommand(c *Context, w http.ResponseWriter, r *http.Request) { props := model.MapFromJson(r.Body) id := props["id"] @@ -465,18 +216,33 @@ func deleteCommand(c *Context, w http.ResponseWriter, r *http.Request) { return } - if result := <-app.Srv.Store.Command().Get(id); result.Err != nil { - c.Err = result.Err + c.LogAudit("attempt") + + cmd, err := app.GetCommand(id) + if err != nil { + c.Err = err + return + } + + if c.TeamId != cmd.TeamId { + c.Err = model.NewAppError("deleteCommand", "api.command.team_mismatch.app_error", nil, "user_id="+c.Session.UserId, http.StatusBadRequest) + return + } + + if !app.SessionHasPermissionToTeam(c.Session, cmd.TeamId, model.PERMISSION_MANAGE_SLASH_COMMANDS) { + c.SetPermissionError(model.PERMISSION_MANAGE_SLASH_COMMANDS) + c.LogAudit("fail - inappropriate permissions") + return + } + + if c.Session.UserId != cmd.CreatorId && !app.SessionHasPermissionToTeam(c.Session, cmd.TeamId, model.PERMISSION_MANAGE_OTHERS_SLASH_COMMANDS) { + c.SetPermissionError(model.PERMISSION_MANAGE_OTHERS_SLASH_COMMANDS) + c.LogAudit("fail - inappropriate permissions") return - } else { - if c.TeamId != result.Data.(*model.Command).TeamId || (c.Session.UserId != result.Data.(*model.Command).CreatorId && !app.SessionHasPermissionToTeam(c.Session, c.TeamId, model.PERMISSION_MANAGE_OTHERS_SLASH_COMMANDS)) { - c.LogAudit("fail - inappropriate permissions") - c.Err = model.NewLocAppError("deleteCommand", "api.command.delete.app_error", nil, "user_id="+c.Session.UserId) - return - } } - if err := (<-app.Srv.Store.Command().Delete(id, model.GetMillis())).Err; err != nil { + err = app.DeleteCommand(cmd.Id) + if err != nil { c.Err = err return } diff --git a/api/command_away.go b/api/command_away.go deleted file mode 100644 index 6a488c081..000000000 --- a/api/command_away.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -package api - -import ( - "github.com/mattermost/platform/app" - "github.com/mattermost/platform/model" -) - -type AwayProvider struct { -} - -const ( - CMD_AWAY = "away" -) - -func init() { - RegisterCommandProvider(&AwayProvider{}) -} - -func (me *AwayProvider) GetTrigger() string { - return CMD_AWAY -} - -func (me *AwayProvider) GetCommand(c *Context) *model.Command { - return &model.Command{ - Trigger: CMD_AWAY, - AutoComplete: true, - AutoCompleteDesc: c.T("api.command_away.desc"), - DisplayName: c.T("api.command_away.name"), - } -} - -func (me *AwayProvider) DoCommand(c *Context, args *model.CommandArgs, message string) *model.CommandResponse { - rmsg := c.T("api.command_away.success") - if len(message) > 0 { - rmsg = message + " " + rmsg - } - app.SetStatusAwayIfNeeded(c.Session.UserId, true) - - return &model.CommandResponse{ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL, Text: rmsg} -} diff --git a/api/command_echo.go b/api/command_echo.go deleted file mode 100644 index 2e931e414..000000000 --- a/api/command_echo.go +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -package api - -import ( - "strconv" - "strings" - "time" - - l4g "github.com/alecthomas/log4go" - "github.com/mattermost/platform/app" - "github.com/mattermost/platform/model" -) - -var echoSem chan bool - -type EchoProvider struct { -} - -const ( - CMD_ECHO = "echo" -) - -func init() { - RegisterCommandProvider(&EchoProvider{}) -} - -func (me *EchoProvider) GetTrigger() string { - return CMD_ECHO -} - -func (me *EchoProvider) GetCommand(c *Context) *model.Command { - return &model.Command{ - Trigger: CMD_ECHO, - AutoComplete: true, - AutoCompleteDesc: c.T("api.command_echo.desc"), - AutoCompleteHint: c.T("api.command_echo.hint"), - DisplayName: c.T("api.command_echo.name"), - } -} - -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{} -} diff --git a/api/command_expand_collapse.go b/api/command_expand_collapse.go deleted file mode 100644 index 5adbf4bab..000000000 --- a/api/command_expand_collapse.go +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -package api - -import ( - "strconv" - - "github.com/mattermost/platform/app" - "github.com/mattermost/platform/model" -) - -type ExpandProvider struct { -} - -type CollapseProvider struct { -} - -const ( - CMD_EXPAND = "expand" - CMD_COLLAPSE = "collapse" -) - -func init() { - RegisterCommandProvider(&ExpandProvider{}) - RegisterCommandProvider(&CollapseProvider{}) -} - -func (me *ExpandProvider) GetTrigger() string { - return CMD_EXPAND -} - -func (me *CollapseProvider) GetTrigger() string { - return CMD_COLLAPSE -} - -func (me *ExpandProvider) GetCommand(c *Context) *model.Command { - return &model.Command{ - Trigger: CMD_EXPAND, - AutoComplete: true, - AutoCompleteDesc: c.T("api.command_expand.desc"), - DisplayName: c.T("api.command_expand.name"), - } -} - -func (me *CollapseProvider) GetCommand(c *Context) *model.Command { - return &model.Command{ - Trigger: CMD_COLLAPSE, - AutoComplete: true, - AutoCompleteDesc: c.T("api.command_collapse.desc"), - DisplayName: c.T("api.command_collapse.name"), - } -} - -func (me *ExpandProvider) DoCommand(c *Context, args *model.CommandArgs, message string) *model.CommandResponse { - return setCollapsePreference(c, false) -} - -func (me *CollapseProvider) DoCommand(c *Context, args *model.CommandArgs, message string) *model.CommandResponse { - return setCollapsePreference(c, true) -} - -func setCollapsePreference(c *Context, isCollapse bool) *model.CommandResponse { - pref := model.Preference{ - UserId: c.Session.UserId, - Category: model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, - Name: model.PREFERENCE_NAME_COLLAPSE_SETTING, - Value: strconv.FormatBool(isCollapse), - } - - if result := <-app.Srv.Store.Preference().Save(&model.Preferences{pref}); result.Err != nil { - return &model.CommandResponse{Text: c.T("api.command_expand_collapse.fail.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} - } - - socketMessage := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_PREFERENCE_CHANGED, "", "", c.Session.UserId, nil) - socketMessage.Add("preference", pref.ToJson()) - go app.Publish(socketMessage) - - var rmsg string - - if isCollapse { - rmsg = c.T("api.command_collapse.success") - } else { - rmsg = c.T("api.command_expand.success") - } - return &model.CommandResponse{ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL, Text: rmsg} -} diff --git a/api/command_invite_people.go b/api/command_invite_people.go deleted file mode 100644 index b8f1827b0..000000000 --- a/api/command_invite_people.go +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -package api - -import ( - "strings" - - l4g "github.com/alecthomas/log4go" - "github.com/mattermost/platform/app" - "github.com/mattermost/platform/model" - "github.com/mattermost/platform/utils" -) - -type InvitePeopleProvider struct { -} - -const ( - CMD_INVITE_PEOPLE = "invite_people" -) - -func init() { - RegisterCommandProvider(&InvitePeopleProvider{}) -} - -func (me *InvitePeopleProvider) GetTrigger() string { - return CMD_INVITE_PEOPLE -} - -func (me *InvitePeopleProvider) GetCommand(c *Context) *model.Command { - return &model.Command{ - Trigger: CMD_INVITE_PEOPLE, - AutoComplete: true, - AutoCompleteDesc: c.T("api.command.invite_people.desc"), - AutoCompleteHint: c.T("api.command.invite_people.hint"), - DisplayName: c.T("api.command.invite_people.name"), - } -} - -func (me *InvitePeopleProvider) DoCommand(c *Context, args *model.CommandArgs, message string) *model.CommandResponse { - if !utils.Cfg.EmailSettings.SendEmailNotifications { - return &model.CommandResponse{ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL, Text: c.T("api.command.invite_people.email_off")} - } - - emailList := strings.Fields(message) - - for i := len(emailList) - 1; i >= 0; i-- { - emailList[i] = strings.Trim(emailList[i], ",") - if !strings.Contains(emailList[i], "@") { - emailList = append(emailList[:i], emailList[i+1:]...) - } - } - - if len(emailList) == 0 { - return &model.CommandResponse{ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL, Text: c.T("api.command.invite_people.no_email")} - } - - if err := app.InviteNewUsersToTeam(emailList, c.TeamId, c.Session.UserId, c.GetSiteURL()); err != nil { - l4g.Error(err.Error()) - return &model.CommandResponse{ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL, Text: c.T("api.command.invite_people.fail")} - } - - return &model.CommandResponse{ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL, Text: c.T("api.command.invite_people.sent")} -} diff --git a/api/command_join.go b/api/command_join.go deleted file mode 100644 index 17deb02b7..000000000 --- a/api/command_join.go +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -package api - -import ( - "github.com/mattermost/platform/app" - "github.com/mattermost/platform/model" -) - -type JoinProvider struct { -} - -const ( - CMD_JOIN = "join" -) - -func init() { - RegisterCommandProvider(&JoinProvider{}) -} - -func (me *JoinProvider) GetTrigger() string { - return CMD_JOIN -} - -func (me *JoinProvider) GetCommand(c *Context) *model.Command { - return &model.Command{ - Trigger: CMD_JOIN, - AutoComplete: true, - AutoCompleteDesc: c.T("api.command_join.desc"), - AutoCompleteHint: c.T("api.command_join.hint"), - DisplayName: c.T("api.command_join.name"), - } -} - -func (me *JoinProvider) DoCommand(c *Context, args *model.CommandArgs, message string) *model.CommandResponse { - if result := <-app.Srv.Store.Channel().GetByName(c.TeamId, message, true); result.Err != nil { - return &model.CommandResponse{Text: c.T("api.command_join.list.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} - } else { - channel := result.Data.(*model.Channel) - - if channel.Name == message { - - if channel.Type != model.CHANNEL_OPEN { - return &model.CommandResponse{Text: c.T("api.command_join.fail.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} - } - - if err := app.JoinChannel(channel, c.Session.UserId); err != nil { - return &model.CommandResponse{Text: c.T("api.command_join.fail.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} - } - - return &model.CommandResponse{GotoLocation: c.GetTeamURL() + "/channels/" + channel.Name, Text: c.T("api.command_join.success"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} - } - } - - return &model.CommandResponse{ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL, Text: c.T("api.command_join.missing.app_error")} -} diff --git a/api/command_loadtest.go b/api/command_loadtest.go deleted file mode 100644 index dfbbadc3b..000000000 --- a/api/command_loadtest.go +++ /dev/null @@ -1,439 +0,0 @@ -// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -package api - -import ( - "io" - "net/http" - "path" - "strconv" - "strings" - - l4g "github.com/alecthomas/log4go" - "github.com/mattermost/platform/app" - "github.com/mattermost/platform/model" - "github.com/mattermost/platform/utils" -) - -var usage = `Mattermost load testing commands to help configure the system - - COMMANDS: - - Setup - Creates a testing environment in current team. - /loadtest setup [teams] [fuzz] - - Example: - /loadtest setup teams fuzz 10 20 50 - - Users - Add a specified number of random users with fuzz text to current team. - /loadtest users [fuzz] - - Example: - /loadtest users fuzz 5 10 - - Channels - Add a specified number of random channels with fuzz text to current team. - /loadtest channels [fuzz] - - Example: - /loadtest channels fuzz 5 10 - - Posts - Add some random posts with fuzz text to current channel. - /loadtest posts [fuzz] - - Example: - /loadtest posts fuzz 5 10 3 - - Url - Add a post containing the text from a given url to current channel. - /loadtest url - - Example: - /loadtest http://www.example.com/sample_file.md - - Json - Add a post using the JSON file as payload to the current channel. - /loadtest json url - - Example - /loadtest json http://www.example.com/sample_body.json - -` - -const ( - CMD_LOADTEST = "loadtest" -) - -type LoadTestProvider struct { -} - -func init() { - if !utils.Cfg.ServiceSettings.EnableTesting { - RegisterCommandProvider(&LoadTestProvider{}) - } -} - -func (me *LoadTestProvider) GetTrigger() string { - return CMD_LOADTEST -} - -func (me *LoadTestProvider) GetCommand(c *Context) *model.Command { - return &model.Command{ - Trigger: CMD_LOADTEST, - AutoComplete: false, - AutoCompleteDesc: "Debug Load Testing", - AutoCompleteHint: "help", - DisplayName: "loadtest", - } -} - -func (me *LoadTestProvider) DoCommand(c *Context, args *model.CommandArgs, message string) *model.CommandResponse { - channelId := args.ChannelId - - //This command is only available when EnableTesting is true - if !utils.Cfg.ServiceSettings.EnableTesting { - return &model.CommandResponse{} - } - - if strings.HasPrefix(message, "setup") { - return me.SetupCommand(c, channelId, message) - } - - if strings.HasPrefix(message, "users") { - return me.UsersCommand(c, channelId, message) - } - - if strings.HasPrefix(message, "channels") { - return me.ChannelsCommand(c, channelId, message) - } - - if strings.HasPrefix(message, "posts") { - return me.PostsCommand(c, channelId, message) - } - - if strings.HasPrefix(message, "url") { - return me.UrlCommand(c, channelId, message) - } - if strings.HasPrefix(message, "json") { - return me.JsonCommand(c, channelId, message) - } - return me.HelpCommand(c, channelId, message) -} - -func (me *LoadTestProvider) HelpCommand(c *Context, channelId string, message string) *model.CommandResponse { - return &model.CommandResponse{Text: usage, ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} -} - -func (me *LoadTestProvider) SetupCommand(c *Context, channelId string, message string) *model.CommandResponse { - tokens := strings.Fields(strings.TrimPrefix(message, "setup")) - doTeams := contains(tokens, "teams") - doFuzz := contains(tokens, "fuzz") - - numArgs := 0 - if doTeams { - numArgs++ - } - if doFuzz { - numArgs++ - } - - var numTeams int - var numChannels int - var numUsers int - var numPosts int - - // Defaults - numTeams = 10 - numChannels = 10 - numUsers = 10 - numPosts = 10 - - if doTeams { - if (len(tokens) - numArgs) >= 4 { - numTeams, _ = strconv.Atoi(tokens[numArgs+0]) - numChannels, _ = strconv.Atoi(tokens[numArgs+1]) - numUsers, _ = strconv.Atoi(tokens[numArgs+2]) - numPosts, _ = strconv.Atoi(tokens[numArgs+3]) - } - } else { - if (len(tokens) - numArgs) >= 3 { - numChannels, _ = strconv.Atoi(tokens[numArgs+0]) - numUsers, _ = strconv.Atoi(tokens[numArgs+1]) - numPosts, _ = strconv.Atoi(tokens[numArgs+2]) - } - } - client := model.NewClient(c.GetSiteURL()) - - if doTeams { - if err := CreateBasicUser(client); err != nil { - return &model.CommandResponse{Text: "Failed to create testing environment", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} - } - client.Login(BTEST_USER_EMAIL, BTEST_USER_PASSWORD) - environment, err := CreateTestEnvironmentWithTeams( - client, - utils.Range{Begin: numTeams, End: numTeams}, - utils.Range{Begin: numChannels, End: numChannels}, - utils.Range{Begin: numUsers, End: numUsers}, - utils.Range{Begin: numPosts, End: numPosts}, - doFuzz) - if err != true { - return &model.CommandResponse{Text: "Failed to create testing environment", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} - } else { - l4g.Info("Testing environment created") - for i := 0; i < len(environment.Teams); i++ { - l4g.Info("Team Created: " + environment.Teams[i].Name) - l4g.Info("\t User to login: " + environment.Environments[i].Users[0].Email + ", " + USER_PASSWORD) - } - } - } else { - - var team *model.Team - if tr := <-app.Srv.Store.Team().Get(c.TeamId); tr.Err != nil { - return &model.CommandResponse{Text: "Failed to create testing environment", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} - } else { - team = tr.Data.(*model.Team) - } - - client.MockSession(c.Session.Token) - client.SetTeamId(c.TeamId) - CreateTestEnvironmentInTeam( - client, - team, - utils.Range{Begin: numChannels, End: numChannels}, - utils.Range{Begin: numUsers, End: numUsers}, - utils.Range{Begin: numPosts, End: numPosts}, - doFuzz) - } - - return &model.CommandResponse{Text: "Created enviroment", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} -} - -func (me *LoadTestProvider) UsersCommand(c *Context, channelId string, message string) *model.CommandResponse { - cmd := strings.TrimSpace(strings.TrimPrefix(message, "users")) - - doFuzz := false - if strings.Index(cmd, "fuzz") == 0 { - doFuzz = true - cmd = strings.TrimSpace(strings.TrimPrefix(cmd, "fuzz")) - } - - usersr, err := parseRange(cmd, "") - if err == false { - usersr = utils.Range{Begin: 2, End: 5} - } - - var team *model.Team - if tr := <-app.Srv.Store.Team().Get(c.TeamId); tr.Err != nil { - return &model.CommandResponse{Text: "Failed to create testing environment", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} - } else { - team = tr.Data.(*model.Team) - } - - client := model.NewClient(c.GetSiteURL()) - client.SetTeamId(team.Id) - userCreator := NewAutoUserCreator(client, team) - userCreator.Fuzzy = doFuzz - userCreator.CreateTestUsers(usersr) - - return &model.CommandResponse{Text: "Added users", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} -} - -func (me *LoadTestProvider) ChannelsCommand(c *Context, channelId string, message string) *model.CommandResponse { - cmd := strings.TrimSpace(strings.TrimPrefix(message, "channels")) - - doFuzz := false - if strings.Index(cmd, "fuzz") == 0 { - doFuzz = true - cmd = strings.TrimSpace(strings.TrimPrefix(cmd, "fuzz")) - } - - channelsr, err := parseRange(cmd, "") - if err == false { - channelsr = utils.Range{Begin: 2, End: 5} - } - - var team *model.Team - if tr := <-app.Srv.Store.Team().Get(c.TeamId); tr.Err != nil { - return &model.CommandResponse{Text: "Failed to create testing environment", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} - } else { - team = tr.Data.(*model.Team) - } - - client := model.NewClient(c.GetSiteURL()) - client.SetTeamId(team.Id) - client.MockSession(c.Session.Token) - channelCreator := NewAutoChannelCreator(client, team) - channelCreator.Fuzzy = doFuzz - channelCreator.CreateTestChannels(channelsr) - - return &model.CommandResponse{Text: "Added channels", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} -} - -func (me *LoadTestProvider) PostsCommand(c *Context, channelId string, message string) *model.CommandResponse { - cmd := strings.TrimSpace(strings.TrimPrefix(message, "posts")) - - doFuzz := false - if strings.Index(cmd, "fuzz") == 0 { - doFuzz = true - cmd = strings.TrimSpace(strings.TrimPrefix(cmd, "fuzz")) - } - - postsr, err := parseRange(cmd, "") - if err == false { - postsr = utils.Range{Begin: 20, End: 30} - } - - tokens := strings.Fields(cmd) - rimages := utils.Range{Begin: 0, End: 0} - if len(tokens) >= 3 { - if numImages, err := strconv.Atoi(tokens[2]); err == nil { - rimages = utils.Range{Begin: numImages, End: numImages} - } - } - - var usernames []string - if result := <-app.Srv.Store.User().GetProfiles(c.TeamId, 0, 1000); result.Err == nil { - profileUsers := result.Data.([]*model.User) - usernames = make([]string, len(profileUsers)) - i := 0 - for _, userprof := range profileUsers { - usernames[i] = userprof.Username - i++ - } - } - - client := model.NewClient(c.GetSiteURL()) - client.SetTeamId(c.TeamId) - client.MockSession(c.Session.Token) - testPoster := NewAutoPostCreator(client, channelId) - testPoster.Fuzzy = doFuzz - testPoster.Users = usernames - - numImages := utils.RandIntFromRange(rimages) - numPosts := utils.RandIntFromRange(postsr) - for i := 0; i < numPosts; i++ { - testPoster.HasImage = (i < numImages) - testPoster.CreateRandomPost() - } - - return &model.CommandResponse{Text: "Added posts", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} -} - -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 parseRange(command string, cmd string) (utils.Range, bool) { - tokens := strings.Fields(strings.TrimPrefix(command, cmd)) - var begin int - var end int - var err1 error - var err2 error - switch { - case len(tokens) == 1: - begin, err1 = strconv.Atoi(tokens[0]) - end = begin - if err1 != nil { - return utils.Range{Begin: 0, End: 0}, false - } - case len(tokens) >= 2: - begin, err1 = strconv.Atoi(tokens[0]) - end, err2 = strconv.Atoi(tokens[1]) - if err1 != nil || err2 != nil { - return utils.Range{Begin: 0, End: 0}, false - } - default: - return utils.Range{Begin: 0, End: 0}, false - } - return utils.Range{Begin: begin, End: end}, true -} - -func contains(items []string, token string) bool { - for _, elem := range items { - if elem == token { - return true - } - } - return false -} diff --git a/api/command_logout.go b/api/command_logout.go deleted file mode 100644 index 0eaa9a0ba..000000000 --- a/api/command_logout.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -package api - -import ( - "github.com/mattermost/platform/app" - "github.com/mattermost/platform/model" -) - -type LogoutProvider struct { -} - -const ( - CMD_LOGOUT = "logout" -) - -func init() { - RegisterCommandProvider(&LogoutProvider{}) -} - -func (me *LogoutProvider) GetTrigger() string { - return CMD_LOGOUT -} - -func (me *LogoutProvider) GetCommand(c *Context) *model.Command { - return &model.Command{ - Trigger: CMD_LOGOUT, - AutoComplete: true, - AutoCompleteDesc: c.T("api.command_logout.desc"), - AutoCompleteHint: "", - DisplayName: c.T("api.command_logout.name"), - } -} - -func (me *LogoutProvider) DoCommand(c *Context, args *model.CommandArgs, message string) *model.CommandResponse { - FAIL := &model.CommandResponse{ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL, Text: c.T("api.command_logout.fail_message")} - SUCCESS := &model.CommandResponse{GotoLocation: "/login"} - - // We can't actually remove the user's cookie from here so we just dump their session and let the browser figure it out - if c.Session.Id != "" { - if err := app.RevokeSessionById(c.Session.Id); err != nil { - return FAIL - } - return SUCCESS - } - return FAIL -} diff --git a/api/command_me.go b/api/command_me.go deleted file mode 100644 index a3cda472a..000000000 --- a/api/command_me.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -package api - -import ( - "github.com/mattermost/platform/model" -) - -type MeProvider struct { -} - -const ( - CMD_ME = "me" -) - -func init() { - RegisterCommandProvider(&MeProvider{}) -} - -func (me *MeProvider) GetTrigger() string { - return CMD_ME -} - -func (me *MeProvider) GetCommand(c *Context) *model.Command { - return &model.Command{ - Trigger: CMD_ME, - AutoComplete: true, - AutoCompleteDesc: c.T("api.command_me.desc"), - AutoCompleteHint: c.T("api.command_me.hint"), - DisplayName: c.T("api.command_me.name"), - } -} - -func (me *MeProvider) DoCommand(c *Context, args *model.CommandArgs, message string) *model.CommandResponse { - return &model.CommandResponse{ResponseType: model.COMMAND_RESPONSE_TYPE_IN_CHANNEL, Text: "*" + message + "*"} -} diff --git a/api/command_msg.go b/api/command_msg.go deleted file mode 100644 index f8c8fae1c..000000000 --- a/api/command_msg.go +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -package api - -import ( - "strings" - - l4g "github.com/alecthomas/log4go" - "github.com/mattermost/platform/app" - "github.com/mattermost/platform/model" -) - -type msgProvider struct { -} - -const ( - CMD_MSG = "msg" -) - -func init() { - RegisterCommandProvider(&msgProvider{}) -} - -func (me *msgProvider) GetTrigger() string { - return CMD_MSG -} - -func (me *msgProvider) GetCommand(c *Context) *model.Command { - return &model.Command{ - Trigger: CMD_MSG, - AutoComplete: true, - AutoCompleteDesc: c.T("api.command_msg.desc"), - AutoCompleteHint: c.T("api.command_msg.hint"), - DisplayName: c.T("api.command_msg.name"), - } -} - -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 { - l4g.Error(result.Err.Error()) - 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, true); 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 { - l4g.Error(err.Error()) - return &model.CommandResponse{Text: c.T("api.command_msg.dm_fail.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL} - } else { - targetChannelId = directChannel.Id - } - } else { - l4g.Error(channel.Err.Error()) - 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 - } - - 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} -} diff --git a/api/command_offline.go b/api/command_offline.go deleted file mode 100644 index a4bcdf8a5..000000000 --- a/api/command_offline.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -package api - -import ( - "github.com/mattermost/platform/app" - "github.com/mattermost/platform/model" -) - -type OfflineProvider struct { -} - -const ( - CMD_OFFLINE = "offline" -) - -func init() { - RegisterCommandProvider(&OfflineProvider{}) -} - -func (me *OfflineProvider) GetTrigger() string { - return CMD_OFFLINE -} - -func (me *OfflineProvider) GetCommand(c *Context) *model.Command { - return &model.Command{ - Trigger: CMD_OFFLINE, - AutoComplete: true, - AutoCompleteDesc: c.T("api.command_offline.desc"), - DisplayName: c.T("api.command_offline.name"), - } -} - -func (me *OfflineProvider) DoCommand(c *Context, args *model.CommandArgs, message string) *model.CommandResponse { - rmsg := c.T("api.command_offline.success") - if len(message) > 0 { - rmsg = message + " " + rmsg - } - app.SetStatusOffline(c.Session.UserId, true) - - return &model.CommandResponse{ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL, Text: rmsg} -} diff --git a/api/command_online.go b/api/command_online.go deleted file mode 100644 index 81d3e1fd6..000000000 --- a/api/command_online.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -package api - -import ( - "github.com/mattermost/platform/app" - "github.com/mattermost/platform/model" -) - -type OnlineProvider struct { -} - -const ( - CMD_ONLINE = "online" -) - -func init() { - RegisterCommandProvider(&OnlineProvider{}) -} - -func (me *OnlineProvider) GetTrigger() string { - return CMD_ONLINE -} - -func (me *OnlineProvider) GetCommand(c *Context) *model.Command { - return &model.Command{ - Trigger: CMD_ONLINE, - AutoComplete: true, - AutoCompleteDesc: c.T("api.command_online.desc"), - DisplayName: c.T("api.command_online.name"), - } -} - -func (me *OnlineProvider) DoCommand(c *Context, args *model.CommandArgs, message string) *model.CommandResponse { - rmsg := c.T("api.command_online.success") - if len(message) > 0 { - rmsg = message + " " + rmsg - } - app.SetStatusOnline(c.Session.UserId, c.Session.Id, true) - - return &model.CommandResponse{ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL, Text: rmsg} -} diff --git a/api/command_shortcuts.go b/api/command_shortcuts.go deleted file mode 100644 index 1664221c1..000000000 --- a/api/command_shortcuts.go +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -package api - -import ( - "bytes" - "strings" - - "github.com/mattermost/platform/model" -) - -type ShortcutsProvider struct { -} - -const ( - CMD_SHORTCUTS = "shortcuts" -) - -func init() { - RegisterCommandProvider(&ShortcutsProvider{}) -} - -func (me *ShortcutsProvider) GetTrigger() string { - return CMD_SHORTCUTS -} - -func (me *ShortcutsProvider) GetCommand(c *Context) *model.Command { - return &model.Command{ - Trigger: CMD_SHORTCUTS, - AutoComplete: true, - AutoCompleteDesc: c.T("api.command_shortcuts.desc"), - AutoCompleteHint: "", - DisplayName: c.T("api.command_shortcuts.name"), - } -} - -func (me *ShortcutsProvider) DoCommand(c *Context, args *model.CommandArgs, message string) *model.CommandResponse { - shortcutIds := [28]string{ - "api.command_shortcuts.header", - // Nav shortcuts - "api.command_shortcuts.nav.header", - "api.command_shortcuts.nav.prev", - "api.command_shortcuts.nav.next", - "api.command_shortcuts.nav.unread_prev", - "api.command_shortcuts.nav.unread_next", - "api.command_shortcuts.nav.switcher", - "api.command_shortcuts.nav.settings", - "api.command_shortcuts.nav.recent_mentions", - // Files shortcuts - "api.command_shortcuts.files.header", - "api.command_shortcuts.files.upload", - // Msg shortcuts - "api.command_shortcuts.msgs.header", - "api.command_shortcuts.msgs.mark_as_read", - "api.command_shortcuts.msgs.reprint_prev", - "api.command_shortcuts.msgs.reprint_next", - "api.command_shortcuts.msgs.edit", - "api.command_shortcuts.msgs.comp_username", - "api.command_shortcuts.msgs.comp_channel", - "api.command_shortcuts.msgs.comp_emoji", - // Browser shortcuts - "api.command_shortcuts.browser.header", - "api.command_shortcuts.browser.channel_prev", - "api.command_shortcuts.browser.channel_next", - "api.command_shortcuts.browser.font_increase", - "api.command_shortcuts.browser.font_decrease", - "api.command_shortcuts.browser.highlight_prev", - "api.command_shortcuts.browser.highlight_next", - "api.command_shortcuts.browser.newline", - } - - var osDependentWords map[string]interface{} - if strings.Contains(message, "mac") { - osDependentWords = map[string]interface{}{ - "CmdOrCtrl": c.T("api.command_shortcuts.cmd"), - "ChannelPrevCmd": c.T("api.command_shortcuts.browser.channel_prev.cmd_mac"), - "ChannelNextCmd": c.T("api.command_shortcuts.browser.channel_next.cmd_mac"), - } - } else { - osDependentWords = map[string]interface{}{ - "CmdOrCtrl": c.T("api.command_shortcuts.ctrl"), - "ChannelPrevCmd": c.T("api.command_shortcuts.browser.channel_prev.cmd"), - "ChannelNextCmd": c.T("api.command_shortcuts.browser.channel_next.cmd"), - } - } - - var buffer bytes.Buffer - for _, element := range shortcutIds { - buffer.WriteString(c.T(element, osDependentWords)) - } - - return &model.CommandResponse{ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL, Text: buffer.String()} -} diff --git a/api/command_shrug.go b/api/command_shrug.go deleted file mode 100644 index 899fcab33..000000000 --- a/api/command_shrug.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -package api - -import ( - "github.com/mattermost/platform/model" -) - -type ShrugProvider struct { -} - -const ( - CMD_SHRUG = "shrug" -) - -func init() { - RegisterCommandProvider(&ShrugProvider{}) -} - -func (me *ShrugProvider) GetTrigger() string { - return CMD_SHRUG -} - -func (me *ShrugProvider) GetCommand(c *Context) *model.Command { - return &model.Command{ - Trigger: CMD_SHRUG, - AutoComplete: true, - AutoCompleteDesc: c.T("api.command_shrug.desc"), - AutoCompleteHint: c.T("api.command_shrug.hint"), - DisplayName: c.T("api.command_shrug.name"), - } -} - -func (me *ShrugProvider) DoCommand(c *Context, args *model.CommandArgs, message string) *model.CommandResponse { - rmsg := `¯\\\_(ツ)\_/¯` - if len(message) > 0 { - rmsg = message + " " + rmsg - } - - return &model.CommandResponse{ResponseType: model.COMMAND_RESPONSE_TYPE_IN_CHANNEL, Text: rmsg} -} -- cgit v1.2.3-1-g7c22