diff --git a/server/command.go b/server/command.go index 192b0fa9..5ce027d5 100644 --- a/server/command.go +++ b/server/command.go @@ -44,6 +44,7 @@ var jiraCommandHandler = CommandHandler{ "instance/settings": executeSettings, "instance/uninstall": executeInstanceUninstall, "instance/v2": executeInstanceV2Legacy, + "instance/default": executeDefaultInstance, "issue/assign": executeAssign, "issue/transition": executeTransition, "issue/unassign": executeUnassign, @@ -97,6 +98,8 @@ const sysAdminHelpText = "\n###### For System Administrators:\n" + "* `/jira instance alias [URL] [alias-name]` - assign an alias to an instance\n" + "* `/jira instance unalias [alias-name]` - remve an alias from an instance\n" + "* `/jira instance v2 ` - Set the Jira instance to process \"v2\" webhooks and subscriptions (not prefixed with the instance ID)\n" + + "* `/jira instance default ` - Set a default instance in case of multiple Jira instances\n" + + "* `/jira webhook [--instance=]` - Show the Mattermost webhook to receive JQL queries\n" + "* `/jira v2revert ` - Revert to V2 jira plugin data model\n" + "" @@ -169,12 +172,13 @@ func addSubCommands(jira *model.AutocompleteData, optInstance bool) { func createInstanceCommand(optInstance bool) *model.AutocompleteData { instance := model.NewAutocompleteData( - "instance", "[alias|connect|disconnect|settings|unalias]", "View and manage installed Jira instances; more commands available to system administrators") + "instance", "[alias|connect|disconnect|settings|unalias|default]", "View and manage installed Jira instances; more commands available to system administrators") instance.AddCommand(createAliasCommand()) instance.AddCommand(createUnAliasCommand()) instance.AddCommand(createConnectCommand()) instance.AddCommand(createSettingsCommand(optInstance)) instance.AddCommand(createDisconnectCommand()) + instance.AddCommand(createDefaultInstanceCommand()) jiraTypes := []model.AutocompleteListItem{ {HelpText: "Jira Server or Datacenter", Item: "server"}, @@ -256,6 +260,13 @@ func createDisconnectCommand() *model.AutocompleteData { return disconnect } +func createDefaultInstanceCommand() *model.AutocompleteData { + defaultInstance := model.NewAutocompleteData( + "default", "[Jira URL]", "Set a default instance in case of multiple Jira instances") + defaultInstance.AddDynamicListArgument("Jira URL", makeAutocompleteRoute(routeAutocompleteInstalledInstanceWithAlias), true) + return defaultInstance +} + func createSettingsCommand(optInstance bool) *model.AutocompleteData { settings := model.NewAutocompleteData( "settings", "[list|notifications]", "View or update your user settings") @@ -424,6 +435,37 @@ func executeDisconnect(p *Plugin, c *plugin.Context, header *model.CommandArgs, return p.responsef(header, "You have successfully disconnected your Jira account (**%s**).", disconnected.DisplayName) } +func executeDefaultInstance(p *Plugin, c *plugin.Context, header *model.CommandArgs, args ...string) *model.CommandResponse { + if len(args) < 1 { + return p.responsef(header, "Please specify the Jira instance URL") + } + + if len(args) > 1 { + return p.help(header) + } + + jiraURL := "" + if len(args) > 0 { + jiraURL = args[0] + } + + instances, err := p.instanceStore.LoadInstances() + if err != nil { + return p.responsef(header, "Failed to load instances. Error: %v.", err) + } + + instance := instances.getByAlias(jiraURL) + if instance != nil { + jiraURL = instance.InstanceID.String() + } + + if err := p.SetDefaultInstance(jiraURL, types.ID(header.UserId)); err != nil { + return p.responsef(header, "Could not complete the **default instance** request. Error: %v", err) + } + + return p.responsef(header, "You have successfully set a default instance for your Jira account (**%s**).", jiraURL) +} + func executeConnect(p *Plugin, c *plugin.Context, header *model.CommandArgs, args ...string) *model.CommandResponse { if len(args) > 1 { return p.help(header) diff --git a/server/instances.go b/server/instances.go index d41efa03..102b3cce 100644 --- a/server/instances.go +++ b/server/instances.go @@ -343,7 +343,7 @@ func (p *Plugin) resolveUserInstanceURL(user *User, instanceURL string) (types.I if user.ConnectedInstances.Len() == 1 { return user.ConnectedInstances.IDs()[0], nil } - return "", errors.Wrap(kvstore.ErrNotFound, "unable to pick the default Jira instance") + return "", errors.New("default jira instance not found, please run `/jira instance default ` to set one") } func (p *Plugin) httpAutocompleteConnect(w http.ResponseWriter, r *http.Request) (int, error) { diff --git a/server/user.go b/server/user.go index 611b6d2e..1e6f0694 100644 --- a/server/user.go +++ b/server/user.go @@ -252,6 +252,25 @@ func (p *Plugin) DisconnectUser(instanceURL string, mattermostUserID types.ID) ( return p.disconnectUser(instance, user) } +func (p *Plugin) SetDefaultInstance(instanceURL string, mattermostUserID types.ID) error { + user, instance, err := p.LoadUserInstance(mattermostUserID, instanceURL) + if err != nil { + return err + } + + if !user.ConnectedInstances.Contains(instance.GetID()) { + return errors.Wrapf(kvstore.ErrNotFound, "user is not connected to %q", instance.GetID()) + } + + user.DefaultInstanceID = instance.GetID() + + if err := p.userStore.StoreUser(user); err != nil { + return err + } + + return nil +} + func (p *Plugin) disconnectUser(instance Instance, user *User) (*Connection, error) { if !user.ConnectedInstances.Contains(instance.GetID()) { return nil, errors.Wrapf(kvstore.ErrNotFound, "user is not connected to %q", instance.GetID())