From 7927b73370d7a9e24000a308c76d53f0a70f909e Mon Sep 17 00:00:00 2001 From: ayas Date: Wed, 19 Aug 2026 15:50:24 +0700 Subject: [PATCH 1/2] Persist the GitLab URL from the setup flow to the plugin configuration The /setup flow stored a custom GitLab URL only on the in-memory FlowManager and in the KV instance, never in the plugin settings. The GitLab API client is rebuilt from config.GitlabURL, so after completing the wizard against a self-hosted instance the OAuth token was sent to gitlab.com and every API call failed with 401. Fixes mattermost/mattermost#37497 --- server/flow.go | 8 +++++--- server/flow_test.go | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 server/flow_test.go diff --git a/server/flow.go b/server/flow.go index 3cd47d7b..33027e14 100644 --- a/server/flow.go +++ b/server/flow.go @@ -421,7 +421,9 @@ func (fm *FlowManager) submitGitlabURL(f *flow.Flow, submitted map[string]any) ( return "", nil, errorList, nil } - fm.gitlabURL = gitlabURL + if err := fm.setGitlabURL(gitlabURL); err != nil { + return "", nil, nil, errors.Wrap(err, "failed to save GitLab URL") + } return "", flow.State{ keyGitlabURL: gitlabURL, @@ -806,8 +808,8 @@ func (fm *FlowManager) submitChannelAnnouncement(f *flow.Flow, submitted map[str func (fm *FlowManager) setGitlabURL(gitlabURL string) error { fm.gitlabURL = gitlabURL - // will need to get gitlab url from plugin config - config := fm.getConfiguration() + config := fm.getConfiguration().Clone() + config.GitlabURL = gitlabURL configMap, err := config.ToMap() if err != nil { diff --git a/server/flow_test.go b/server/flow_test.go new file mode 100644 index 00000000..8bbfb18a --- /dev/null +++ b/server/flow_test.go @@ -0,0 +1,43 @@ +// Copyright (c) 2019-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +package main + +import ( + "testing" + + "github.com/mattermost/mattermost/server/public/plugin/plugintest" + "github.com/mattermost/mattermost/server/public/pluginapi" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" +) + +func TestSetGitlabURL(t *testing.T) { + config := &configuration{ + GitlabURL: "https://gitlab.com", + } + + var savedConfig map[string]any + api := &plugintest.API{} + api.On("SavePluginConfig", mock.Anything).Run(func(args mock.Arguments) { + savedConfig = args.Get(0).(map[string]any) + }).Return(nil).Once() + + fm := &FlowManager{ + client: pluginapi.NewClient(api, nil), + getConfiguration: func() *configuration { return config }, + } + + err := fm.setGitlabURL("https://git.example.com") + require.NoError(t, err) + + assert.Equal(t, "https://git.example.com", fm.gitlabURL) + + require.NotNil(t, savedConfig) + assert.Equal(t, "https://git.example.com", savedConfig["gitlaburl"]) + + assert.Equal(t, "https://gitlab.com", config.GitlabURL) + + api.AssertExpectations(t) +} From e2e88e55db8be1269c005a02405d3a349311dbbb Mon Sep 17 00:00:00 2001 From: ayas Date: Wed, 19 Aug 2026 16:03:28 +0700 Subject: [PATCH 2/2] Assign the flow manager URL only after the plugin config saves --- server/flow.go | 4 ++-- server/flow_test.go | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/server/flow.go b/server/flow.go index 33027e14..2cf57b59 100644 --- a/server/flow.go +++ b/server/flow.go @@ -806,8 +806,6 @@ func (fm *FlowManager) submitChannelAnnouncement(f *flow.Flow, submitted map[str } func (fm *FlowManager) setGitlabURL(gitlabURL string) error { - fm.gitlabURL = gitlabURL - config := fm.getConfiguration().Clone() config.GitlabURL = gitlabURL @@ -821,6 +819,8 @@ func (fm *FlowManager) setGitlabURL(gitlabURL string) error { return errors.Wrap(err, "failed to save plugin config") } + fm.gitlabURL = gitlabURL + return nil } diff --git a/server/flow_test.go b/server/flow_test.go index 8bbfb18a..d6f7aac1 100644 --- a/server/flow_test.go +++ b/server/flow_test.go @@ -4,8 +4,10 @@ package main import ( + "net/http" "testing" + "github.com/mattermost/mattermost/server/public/model" "github.com/mattermost/mattermost/server/public/plugin/plugintest" "github.com/mattermost/mattermost/server/public/pluginapi" "github.com/stretchr/testify/assert" @@ -41,3 +43,24 @@ func TestSetGitlabURL(t *testing.T) { api.AssertExpectations(t) } + +func TestSetGitlabURLSaveFailure(t *testing.T) { + config := &configuration{ + GitlabURL: "https://gitlab.com", + } + + api := &plugintest.API{} + api.On("SavePluginConfig", mock.Anything).Return(model.NewAppError("SavePluginConfig", "app.plugin.config.app_error", nil, "", http.StatusInternalServerError)).Once() + + fm := &FlowManager{ + client: pluginapi.NewClient(api, nil), + getConfiguration: func() *configuration { return config }, + } + + err := fm.setGitlabURL("https://git.example.com") + require.Error(t, err) + + assert.Empty(t, fm.gitlabURL) + + api.AssertExpectations(t) +}