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