diff --git a/server/plugin/mm_34646_token_refresh.go b/server/plugin/mm_34646_token_refresh.go index 1511564be..62c7ccb72 100644 --- a/server/plugin/mm_34646_token_refresh.go +++ b/server/plugin/mm_34646_token_refresh.go @@ -7,17 +7,34 @@ import ( "github.com/google/go-github/v41/github" "github.com/pkg/errors" + + "github.com/mattermost/mattermost-plugin-api/cluster" ) const pageSize = 100 const delayBetweenUsers = 1 * time.Second -const delayToStart = 5 * time.Minute +const delayToStart = 1 * time.Minute func (p *Plugin) forceResetAllMM34646() error { config := p.getConfiguration() ctx := context.Background() time.Sleep(delayToStart) + data, appErr := p.API.KVGet(mm34646DoneKey) + if appErr != nil { + return errors.Wrap(appErr, "failed check whether MM-34646 refresh is already done") + } + if len(data) > 0 { + // Already done + return nil + } + + m, err := cluster.NewMutex(p.API, mm34646MutexKey) + if err != nil { + return errors.Wrap(err, "failed to create mutex") + } + m.Lock() + defer m.Unlock() for page := 0; ; page++ { keys, appErr := p.API.KVList(page, pageSize) @@ -53,7 +70,7 @@ func (p *Plugin) forceResetAllMM34646() error { continue } - _, err = p.forceResetUserTokenMM34646(ctx, config, *info) + _, err = p.forceResetUserTokenMM34646(ctx, config, info) if err != nil { p.API.LogError("failed to reset GitHub user token", "key", key, "user_id", tryInfo.UserID, "error", err.Error()) @@ -63,14 +80,16 @@ func (p *Plugin) forceResetAllMM34646() error { time.Sleep(delayBetweenUsers) } - if len(keys) < pageSize { + if len(keys) == 0 { break } } + + _ = p.API.KVSet(mm34646DoneKey, []byte("done")) return nil } -func (p *Plugin) forceResetUserTokenMM34646(ctx context.Context, config *Configuration, info GitHubUserInfo) (string, error) { +func (p *Plugin) forceResetUserTokenMM34646(ctx context.Context, config *Configuration, info *GitHubUserInfo) (string, error) { if info.MM34646ResetTokenDone { return info.Token.AccessToken, nil } @@ -90,7 +109,7 @@ func (p *Plugin) forceResetUserTokenMM34646(ctx context.Context, config *Configu info.Token.AccessToken = *a.Token info.MM34646ResetTokenDone = true - err = p.storeGitHubUserInfo(&info) + err = p.storeGitHubUserInfo(info) if err != nil { return "", errors.Wrap(err, "failed to store updated GitHubUserInfo") } diff --git a/server/plugin/plugin.go b/server/plugin/plugin.go index cde8ad3db..5dc367947 100644 --- a/server/plugin/plugin.go +++ b/server/plugin/plugin.go @@ -31,6 +31,9 @@ const ( githubUsernameKey = "_githubusername" githubPrivateRepoKey = "_githubprivate" + mm34646MutexKey = "mm34646_token_reset_mutex" + mm34646DoneKey = "mm34646_token_reset_done" + wsEventConnect = "connect" wsEventDisconnect = "disconnect" // WSEventConfigUpdate is the WebSocket event to update the configurations on webapp. @@ -121,17 +124,7 @@ func (p *Plugin) GetGitHubClient(ctx context.Context, userID string) (*github.Cl } func (p *Plugin) githubConnectUser(ctx context.Context, info *GitHubUserInfo) *github.Client { - access := info.Token.AccessToken - config := p.getConfiguration() - updated, err := p.forceResetUserTokenMM34646(ctx, config, *info) - if err == nil { - access = updated - } else { - p.API.LogInfo("Failed to refresh access token", "error", err.Error()) - } - tok := *info.Token - tok.AccessToken = access return p.githubConnectToken(tok) } @@ -242,9 +235,9 @@ func (p *Plugin) OnActivate() error { registerGitHubToUsernameMappingCallback(p.getGitHubToUsernameMapping) go func() { - err := p.forceResetAllMM34646() - if err != nil { - p.API.LogDebug("failed to reset user tokens", "error", err.Error()) + resetErr := p.forceResetAllMM34646() + if resetErr != nil { + p.API.LogDebug("failed to reset user tokens", "error", resetErr.Error()) } }() return nil