github.com/jfrerich/mattermost-server@v5.8.0-rc2+incompatible/cmd/mattermost/commands/command.go (about)

     1  // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package commands
     5  
     6  import (
     7  	"errors"
     8  	"strings"
     9  
    10  	"fmt"
    11  
    12  	"github.com/mattermost/mattermost-server/app"
    13  	"github.com/mattermost/mattermost-server/model"
    14  	"github.com/spf13/cobra"
    15  )
    16  
    17  var CommandCmd = &cobra.Command{
    18  	Use:   "command",
    19  	Short: "Management of slash commands",
    20  }
    21  
    22  var CommandCreateCmd = &cobra.Command{
    23  	Use:     "create [team]",
    24  	Short:   "Create a custom slash command",
    25  	Long:    `Create a custom slash command for the specified team.`,
    26  	Args:    cobra.MinimumNArgs(1),
    27  	Example: `  command create myteam --title MyCommand --description "My Command Description" --trigger-word mycommand --url http://localhost:8000/my-slash-handler --creator myusername --response-username my-bot-username --icon http://localhost:8000/my-slash-handler-bot-icon.png --autocomplete --post`,
    28  	RunE:    createCommandCmdF,
    29  }
    30  
    31  var CommandMoveCmd = &cobra.Command{
    32  	Use:     "move",
    33  	Short:   "Move a slash command to a different team",
    34  	Long:    `Move a slash command to a different team. Commands can be specified by [team]:[command-trigger-word]. ie. myteam:trigger or by command ID.`,
    35  	Example: `  command move newteam oldteam:command`,
    36  	RunE:    moveCommandCmdF,
    37  }
    38  
    39  var CommandListCmd = &cobra.Command{
    40  	Use:     "list",
    41  	Short:   "List all commands on specified teams.",
    42  	Long:    `List all commands on specified teams.`,
    43  	Example: ` command list myteam`,
    44  	RunE:    listCommandCmdF,
    45  }
    46  
    47  var CommandDeleteCmd = &cobra.Command{
    48  	Use:     "delete",
    49  	Short:   "Delete a slash command",
    50  	Long:    `Delete a slash command. Commands can be specified by command ID.`,
    51  	Example: `  command delete commandID`,
    52  	Args:    cobra.ExactArgs(1),
    53  	RunE:    deleteCommandCmdF,
    54  }
    55  
    56  func init() {
    57  	CommandCreateCmd.Flags().String("title", "", "Command Title")
    58  	CommandCreateCmd.Flags().String("description", "", "Command Description")
    59  	CommandCreateCmd.Flags().String("trigger-word", "", "Command Trigger Word (required)")
    60  	CommandCreateCmd.MarkFlagRequired("trigger-word")
    61  	CommandCreateCmd.Flags().String("url", "", "Command Callback URL (required)")
    62  	CommandCreateCmd.MarkFlagRequired("url")
    63  	CommandCreateCmd.Flags().String("creator", "", "Command Creator's Username (required)")
    64  	CommandCreateCmd.MarkFlagRequired("creator")
    65  	CommandCreateCmd.Flags().String("response-username", "", "Command Response Username")
    66  	CommandCreateCmd.Flags().String("icon", "", "Command Icon URL")
    67  	CommandCreateCmd.Flags().Bool("autocomplete", false, "Show Command in autocomplete list")
    68  	CommandCreateCmd.Flags().String("autocompleteDesc", "", "Short Command Description for autocomplete list")
    69  	CommandCreateCmd.Flags().String("autocompleteHint", "", "Command Arguments displayed as help in autocomplete list")
    70  	CommandCreateCmd.Flags().Bool("post", false, "Use POST method for Callback URL")
    71  
    72  	CommandCmd.AddCommand(
    73  		CommandCreateCmd,
    74  		CommandMoveCmd,
    75  		CommandListCmd,
    76  		CommandDeleteCmd,
    77  	)
    78  	RootCmd.AddCommand(CommandCmd)
    79  }
    80  
    81  func createCommandCmdF(command *cobra.Command, args []string) error {
    82  	a, err := InitDBCommandContextCobra(command)
    83  	if err != nil {
    84  		return err
    85  	}
    86  	defer a.Shutdown()
    87  
    88  	team := getTeamFromTeamArg(a, args[0])
    89  	if team == nil {
    90  		return errors.New("unable to find team '" + args[0] + "'")
    91  	}
    92  
    93  	// get the creator
    94  	creator, _ := command.Flags().GetString("creator")
    95  	user := getUserFromUserArg(a, creator)
    96  	if user == nil {
    97  		return errors.New("unable to find user '" + creator + "'")
    98  	}
    99  
   100  	// check if creator has permission to create slash commands
   101  	if !a.HasPermissionToTeam(user.Id, team.Id, model.PERMISSION_MANAGE_SLASH_COMMANDS) {
   102  		return errors.New("the creator must be a user who has permissions to manage slash commands")
   103  	}
   104  
   105  	title, _ := command.Flags().GetString("title")
   106  	description, _ := command.Flags().GetString("description")
   107  	trigger, _ := command.Flags().GetString("trigger-word")
   108  
   109  	if strings.HasPrefix(trigger, "/") {
   110  		return errors.New("a trigger word cannot begin with a /")
   111  	}
   112  	if strings.Contains(trigger, " ") {
   113  		return errors.New("a trigger word must not contain spaces")
   114  	}
   115  
   116  	url, _ := command.Flags().GetString("url")
   117  	responseUsername, _ := command.Flags().GetString("response-username")
   118  	icon, _ := command.Flags().GetString("icon")
   119  	autocomplete, _ := command.Flags().GetBool("autocomplete")
   120  	autocompleteDesc, _ := command.Flags().GetString("autocompleteDesc")
   121  	autocompleteHint, _ := command.Flags().GetString("autocompleteHint")
   122  	post, errp := command.Flags().GetBool("post")
   123  	method := "P"
   124  	if errp != nil || post == false {
   125  		method = "G"
   126  	}
   127  
   128  	newCommand := &model.Command{
   129  		CreatorId:        user.Id,
   130  		TeamId:           team.Id,
   131  		Trigger:          trigger,
   132  		Method:           method,
   133  		Username:         responseUsername,
   134  		IconURL:          icon,
   135  		AutoComplete:     autocomplete,
   136  		AutoCompleteDesc: autocompleteDesc,
   137  		AutoCompleteHint: autocompleteHint,
   138  		DisplayName:      title,
   139  		Description:      description,
   140  		URL:              url,
   141  	}
   142  
   143  	if _, err := a.CreateCommand(newCommand); err != nil {
   144  		return errors.New("unable to create command '" + newCommand.DisplayName + "'. " + err.Error())
   145  	}
   146  	CommandPrettyPrintln("created command '" + newCommand.DisplayName + "'")
   147  
   148  	return nil
   149  }
   150  
   151  func moveCommandCmdF(command *cobra.Command, args []string) error {
   152  	a, err := InitDBCommandContextCobra(command)
   153  	if err != nil {
   154  		return err
   155  	}
   156  	defer a.Shutdown()
   157  
   158  	if len(args) < 2 {
   159  		return errors.New("Enter the destination team and at least one comamnd to move.")
   160  	}
   161  
   162  	team := getTeamFromTeamArg(a, args[0])
   163  	if team == nil {
   164  		return errors.New("Unable to find destination team '" + args[0] + "'")
   165  	}
   166  
   167  	commands := getCommandsFromCommandArgs(a, args[1:])
   168  	for i, command := range commands {
   169  		if command == nil {
   170  			CommandPrintErrorln("Unable to find command '" + args[i+1] + "'")
   171  			continue
   172  		}
   173  		if err := moveCommand(a, team, command); err != nil {
   174  			CommandPrintErrorln("Unable to move command '" + command.DisplayName + "' error: " + err.Error())
   175  		} else {
   176  			CommandPrettyPrintln("Moved command '" + command.DisplayName + "'")
   177  		}
   178  	}
   179  
   180  	return nil
   181  }
   182  
   183  func moveCommand(a *app.App, team *model.Team, command *model.Command) *model.AppError {
   184  	return a.MoveCommand(team, command)
   185  }
   186  
   187  func listCommandCmdF(command *cobra.Command, args []string) error {
   188  	a, err := InitDBCommandContextCobra(command)
   189  	if err != nil {
   190  		return err
   191  	}
   192  	defer a.Shutdown()
   193  
   194  	var teams []*model.Team
   195  	if len(args) < 1 {
   196  		teamList, err := a.GetAllTeams()
   197  		if err != nil {
   198  			return err
   199  		}
   200  		teams = teamList
   201  	} else {
   202  		teams = getTeamsFromTeamArgs(a, args)
   203  	}
   204  
   205  	for i, team := range teams {
   206  		if team == nil {
   207  			CommandPrintErrorln("Unable to find team '" + args[i] + "'")
   208  			continue
   209  		}
   210  		result := <-a.Srv.Store.Command().GetByTeam(team.Id)
   211  		if result.Err != nil {
   212  			CommandPrintErrorln("Unable to list commands for '" + args[i] + "'")
   213  			continue
   214  		}
   215  		commands := result.Data.([]*model.Command)
   216  		for _, command := range commands {
   217  			commandListItem := fmt.Sprintf("%s: %s (team: %s)", command.Id, command.DisplayName, team.Name)
   218  			CommandPrettyPrintln(commandListItem)
   219  		}
   220  	}
   221  	return nil
   222  }
   223  
   224  func deleteCommandCmdF(command *cobra.Command, args []string) error {
   225  	a, err := InitDBCommandContextCobra(command)
   226  	if err != nil {
   227  		return err
   228  	}
   229  	defer a.Shutdown()
   230  
   231  	slashCommand := getCommandFromCommandArg(a, args[0])
   232  	if slashCommand == nil {
   233  		command.SilenceUsage = true
   234  		return errors.New("Unable to find command '" + args[0] + "'")
   235  	}
   236  	if err := a.DeleteCommand(slashCommand.Id); err != nil {
   237  		command.SilenceUsage = true
   238  		return errors.New("Unable to delete command '" + slashCommand.Id + "' error: " + err.Error())
   239  	}
   240  	CommandPrettyPrintln("Deleted command '" + slashCommand.Id + "' (" + slashCommand.DisplayName + ")")
   241  	return nil
   242  }