diff --git a/app/server.go b/app/server.go index 65471dd1e7..6ff93fae91 100644 --- a/app/server.go +++ b/app/server.go @@ -1491,7 +1491,11 @@ func doSecurity(s *Server) { } func doTokenCleanup(s *Server) { - s.Store.Token().Cleanup() + expiry := model.GetMillis() - model.MaxTokenExipryTime + + mlog.Debug("Cleaning up token store.") + + s.Store.Token().Cleanup(expiry) } func doCommandWebhookCleanup(s *Server) { diff --git a/store/opentracinglayer/opentracinglayer.go b/store/opentracinglayer/opentracinglayer.go index 0d27fbfea2..6113fefeb8 100644 --- a/store/opentracinglayer/opentracinglayer.go +++ b/store/opentracinglayer/opentracinglayer.go @@ -9465,7 +9465,7 @@ func (s *OpenTracingLayerThreadStore) UpdateUnreadsByChannel(userId string, chan return err } -func (s *OpenTracingLayerTokenStore) Cleanup() { +func (s *OpenTracingLayerTokenStore) Cleanup(expiryTime int64) { origCtx := s.Root.Store.Context() span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "TokenStore.Cleanup") s.Root.Store.SetContext(newCtx) @@ -9474,7 +9474,7 @@ func (s *OpenTracingLayerTokenStore) Cleanup() { }() defer span.Finish() - s.TokenStore.Cleanup() + s.TokenStore.Cleanup(expiryTime) } diff --git a/store/retrylayer/retrylayer.go b/store/retrylayer/retrylayer.go index 78e7c2616a..cac13ab5cb 100644 --- a/store/retrylayer/retrylayer.go +++ b/store/retrylayer/retrylayer.go @@ -10813,9 +10813,9 @@ func (s *RetryLayerThreadStore) UpdateUnreadsByChannel(userId string, changedThr } -func (s *RetryLayerTokenStore) Cleanup() { +func (s *RetryLayerTokenStore) Cleanup(expiryTime int64) { - s.TokenStore.Cleanup() + s.TokenStore.Cleanup(expiryTime) } diff --git a/store/sqlstore/tokens_store.go b/store/sqlstore/tokens_store.go index 1201419039..bba9c42090 100644 --- a/store/sqlstore/tokens_store.go +++ b/store/sqlstore/tokens_store.go @@ -74,10 +74,8 @@ func (s SqlTokenStore) GetByToken(tokenString string) (*model.Token, error) { return &token, nil } -func (s SqlTokenStore) Cleanup() { - mlog.Debug("Cleaning up token store.") - deltime := model.GetMillis() - model.MaxTokenExipryTime - if _, err := s.GetMasterX().Exec("DELETE FROM Tokens WHERE CreateAt < ?", deltime); err != nil { +func (s SqlTokenStore) Cleanup(expiryTime int64) { + if _, err := s.GetMasterX().Exec("DELETE FROM Tokens WHERE CreateAt < ?", expiryTime); err != nil { mlog.Error("Unable to cleanup token store.") } } diff --git a/store/sqlstore/tokens_store_test.go b/store/sqlstore/tokens_store_test.go new file mode 100644 index 0000000000..24388620b3 --- /dev/null +++ b/store/sqlstore/tokens_store_test.go @@ -0,0 +1,14 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +package sqlstore + +import ( + "testing" + + "github.com/mattermost/mattermost-server/v6/store/storetest" +) + +func TestTokensStore(t *testing.T) { + StoreTest(t, storetest.TestTokensStore) +} diff --git a/store/store.go b/store/store.go index 267a884937..4e7df43b54 100644 --- a/store/store.go +++ b/store/store.go @@ -610,7 +610,7 @@ type TokenStore interface { Save(recovery *model.Token) error Delete(token string) error GetByToken(token string) (*model.Token, error) - Cleanup() + Cleanup(expiryTime int64) GetAllTokensByType(tokenType string) ([]*model.Token, error) RemoveAllTokensByType(tokenType string) error } diff --git a/store/storetest/mocks/TokenStore.go b/store/storetest/mocks/TokenStore.go index 8221856304..6a26eab139 100644 --- a/store/storetest/mocks/TokenStore.go +++ b/store/storetest/mocks/TokenStore.go @@ -14,9 +14,9 @@ type TokenStore struct { mock.Mock } -// Cleanup provides a mock function with given fields: -func (_m *TokenStore) Cleanup() { - _m.Called() +// Cleanup provides a mock function with given fields: expiryTime +func (_m *TokenStore) Cleanup(expiryTime int64) { + _m.Called(expiryTime) } // Delete provides a mock function with given fields: token diff --git a/store/storetest/tokens_store.go b/store/storetest/tokens_store.go new file mode 100644 index 0000000000..0704a1139e --- /dev/null +++ b/store/storetest/tokens_store.go @@ -0,0 +1,42 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +package storetest + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/mattermost/mattermost-server/v6/model" + "github.com/mattermost/mattermost-server/v6/store" +) + +func TestTokensStore(t *testing.T, ss store.Store) { + t.Run("TokensCleanup", func(t *testing.T) { testTokensCleanup(t, ss) }) +} + +func testTokensCleanup(t *testing.T, ss store.Store) { + now := model.GetMillis() + + for i := 0; i < 10; i++ { + err := ss.Token().Save(&model.Token{ + Token: model.NewRandomString(model.TokenSize), + CreateAt: now - int64(i), + Type: model.TokenTypeOAuth, + Extra: "", + }) + require.NoError(t, err) + } + + tokens, err := ss.Token().GetAllTokensByType(model.TokenTypeOAuth) + require.NoError(t, err) + assert.Len(t, tokens, 10) + + ss.Token().Cleanup(now + int64(1)) + + tokens, err = ss.Token().GetAllTokensByType(model.TokenTypeOAuth) + require.NoError(t, err) + assert.Len(t, tokens, 0) +} diff --git a/store/timerlayer/timerlayer.go b/store/timerlayer/timerlayer.go index 3c1b8ee3bb..51d836aacc 100644 --- a/store/timerlayer/timerlayer.go +++ b/store/timerlayer/timerlayer.go @@ -8519,10 +8519,10 @@ func (s *TimerLayerThreadStore) UpdateUnreadsByChannel(userId string, changedThr return err } -func (s *TimerLayerTokenStore) Cleanup() { +func (s *TimerLayerTokenStore) Cleanup(expiryTime int64) { start := timemodule.Now() - s.TokenStore.Cleanup() + s.TokenStore.Cleanup(expiryTime) elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second) if s.Root.Metrics != nil {