From 618a104e6616e56e3673e9a74ddc226faf7a3af6 Mon Sep 17 00:00:00 2001 From: kshitij katiyar Date: Fri, 2 Aug 2024 16:58:19 +0530 Subject: [PATCH 1/4] [MM-803]: Added a slash command to set a default jira instance in case of multiple instances --- server/command.go | 41 ++++++++++++++++++++++++++++++++++++++++- server/instances.go | 2 +- server/user.go | 20 ++++++++++++++++++++ 3 files changed, 61 insertions(+), 2 deletions(-) diff --git a/server/command.go b/server/command.go index d82cc6272..8c6b40c8c 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, @@ -94,6 +95,7 @@ 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" + "" @@ -167,12 +169,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"}, @@ -254,6 +257,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") @@ -422,6 +432,35 @@ 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() + } + + err = p.SetDefaultInstance(jiraURL, types.ID(header.UserId)) + if 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 c85e669a8..9b044569c 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 611b6d2ef..c366584bf 100644 --- a/server/user.go +++ b/server/user.go @@ -252,6 +252,26 @@ 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() + + err = p.userStore.StoreUser(user) + if 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()) From e41da68f2d79814c3f0c5bcfe26a011058626e0c Mon Sep 17 00:00:00 2001 From: kshitij katiyar Date: Fri, 2 Aug 2024 17:31:05 +0530 Subject: [PATCH 2/4] [MM-803]: Improved code quality and added required line gaps --- server/command.go | 4 ++-- server/user.go | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/server/command.go b/server/command.go index 8c6b40c8c..e552177d6 100644 --- a/server/command.go +++ b/server/command.go @@ -448,13 +448,13 @@ func executeDefaultInstance(p *Plugin, c *plugin.Context, header *model.CommandA 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() } - err = p.SetDefaultInstance(jiraURL, types.ID(header.UserId)) - if err != nil { + 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) } diff --git a/server/user.go b/server/user.go index c366584bf..1e6f06947 100644 --- a/server/user.go +++ b/server/user.go @@ -264,8 +264,7 @@ func (p *Plugin) SetDefaultInstance(instanceURL string, mattermostUserID types.I user.DefaultInstanceID = instance.GetID() - err = p.userStore.StoreUser(user) - if err != nil { + if err := p.userStore.StoreUser(user); err != nil { return err } From 1ab06cfed2ad69a64fdb9e261a282c0439b8597d Mon Sep 17 00:00:00 2001 From: Doug Lauder Date: Tue, 22 Oct 2024 17:06:30 -0400 Subject: [PATCH 3/4] Update server/command.go --- server/command.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/command.go b/server/command.go index 312841441..6422eb108 100644 --- a/server/command.go +++ b/server/command.go @@ -434,7 +434,7 @@ func executeDisconnect(p *Plugin, c *plugin.Context, header *model.CommandArgs, 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") + return p.responsef(header, "Please specify the Jira instance URL") } if len(args) > 1 { From bc47894ceccbfff51987f705c9210de36c6722d0 Mon Sep 17 00:00:00 2001 From: Raghav Aggarwal Date: Thu, 24 Oct 2024 15:27:20 +0530 Subject: [PATCH 4/4] Apply suggestions from code review --- server/command.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/command.go b/server/command.go index 6422eb108..aac6a687c 100644 --- a/server/command.go +++ b/server/command.go @@ -440,10 +440,12 @@ func executeDefaultInstance(p *Plugin, c *plugin.Context, header *model.CommandA 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)