Revert "MM-53879: Fix recursive loading of license (#24200)" (#24498)

This reverts commit dd73c2af0f.
This commit is contained in:
Agniva De Sarker 2023-09-07 20:58:20 +05:30 committed by GitHub
parent 01cf4b459f
commit acdfefe456
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 165 additions and 31 deletions

View file

@ -319,7 +319,11 @@ func invalidateCaches(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
c.App.Srv().InvalidateAllCaches()
appErr := c.App.Srv().InvalidateAllCaches()
if appErr != nil {
c.Err = appErr
return
}
auditRec.Success()

View file

@ -3909,7 +3909,8 @@ func TestLoginWithLag(t *testing.T) {
_, _, err := th.Client.Login(context.Background(), th.BasicUser.Email, th.BasicUser.Password)
require.NoError(t, err)
th.App.Srv().InvalidateAllCaches()
appErr = th.App.Srv().InvalidateAllCaches()
require.Nil(t, appErr)
session, appErr := th.App.GetSession(th.Client.AuthToken)
require.Nil(t, appErr)

View file

@ -137,8 +137,8 @@ func (a *App) GetClusterStatus() []*model.ClusterInfo {
return infos
}
func (s *Server) InvalidateAllCaches() {
s.platform.InvalidateAllCaches()
func (s *Server) InvalidateAllCaches() *model.AppError {
return s.platform.InvalidateAllCaches()
}
func (s *Server) InvalidateAllCachesSkipSend() {

View file

@ -131,6 +131,10 @@ func (s *Server) License() *model.License {
return s.platform.License()
}
func (s *Server) LoadLicense() {
s.platform.LoadLicense()
}
func (s *Server) SaveLicense(licenseBytes []byte) (*model.License, *model.AppError) {
return s.platform.SaveLicense(licenseBytes)
}

View file

@ -0,0 +1,109 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
package app
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/mattermost/mattermost/server/public/model"
)
func TestLoadLicense(t *testing.T) {
th := Setup(t)
defer th.TearDown()
th.App.Srv().LoadLicense()
require.Nil(t, th.App.Srv().License(), "shouldn't have a valid license")
}
func TestSaveLicense(t *testing.T) {
th := Setup(t)
defer th.TearDown()
b1 := []byte("junk")
_, err := th.App.Srv().SaveLicense(b1)
require.NotNil(t, err, "shouldn't have saved license")
}
func TestRemoveLicense(t *testing.T) {
th := Setup(t)
defer th.TearDown()
err := th.App.Srv().RemoveLicense()
require.Nil(t, err, "should have removed license")
}
func TestSetLicense(t *testing.T) {
th := Setup(t)
defer th.TearDown()
l1 := &model.License{}
l1.Features = &model.Features{}
l1.Customer = &model.Customer{}
l1.StartsAt = model.GetMillis() - 1000
l1.ExpiresAt = model.GetMillis() + 100000
ok := th.App.Srv().SetLicense(l1)
require.True(t, ok, "license should have worked")
l3 := &model.License{}
l3.Features = &model.Features{}
l3.Customer = &model.Customer{}
l3.StartsAt = model.GetMillis() + 10000
l3.ExpiresAt = model.GetMillis() + 100000
ok = th.App.Srv().SetLicense(l3)
require.True(t, ok, "license should have passed")
}
func TestGetSanitizedClientLicense(t *testing.T) {
th := Setup(t)
defer th.TearDown()
setLicense(th, nil)
m := th.App.Srv().GetSanitizedClientLicense()
_, ok := m["Name"]
assert.False(t, ok)
_, ok = m["SkuName"]
assert.False(t, ok)
}
func TestGenerateRenewalToken(t *testing.T) {
th := Setup(t)
defer th.TearDown()
t.Run("renewal token generated correctly", func(t *testing.T) {
setLicense(th, nil)
token, appErr := th.App.Srv().GenerateRenewalToken(JWTDefaultTokenExpiration)
require.Nil(t, appErr)
require.NotEmpty(t, token)
})
t.Run("return error if there is no active license", func(t *testing.T) {
th.App.Srv().SetLicense(nil)
_, appErr := th.App.Srv().GenerateRenewalToken(JWTDefaultTokenExpiration)
require.NotNil(t, appErr)
})
}
func setLicense(th *TestHelper, customer *model.Customer) {
l1 := &model.License{}
l1.Features = &model.Features{}
if customer != nil {
l1.Customer = customer
} else {
l1.Customer = &model.Customer{}
l1.Customer.Name = "TestName"
l1.Customer.Email = "test@example.com"
}
l1.SkuName = "SKU NAME"
l1.SkuShortName = "SKU SHORT NAME"
l1.StartsAt = model.GetMillis() - 1000
l1.ExpiresAt = model.GetMillis() + 100000
th.App.Srv().SetLicense(l1)
}

View file

@ -99,7 +99,8 @@ func TestSendNotifications(t *testing.T) {
_, appErr = th.App.UpdateActive(th.Context, th.BasicUser2, false)
require.Nil(t, appErr)
th.App.Srv().InvalidateAllCaches()
appErr = th.App.Srv().InvalidateAllCaches()
require.Nil(t, appErr)
post3, appErr := th.App.CreatePostMissingChannel(th.Context, &model.Post{
UserId: th.BasicUser.Id,

View file

@ -113,7 +113,9 @@ func (a *App) DeleteOAuthApp(appID string) *model.AppError {
return model.NewAppError("DeleteOAuthApp", "app.oauth.delete_app.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
}
a.Srv().InvalidateAllCaches()
if err := a.Srv().InvalidateAllCaches(); err != nil {
mlog.Warn("error in invalidating cache", mlog.Err(err))
}
return nil
}

View file

@ -17,7 +17,6 @@ func (ps *PlatformService) RegisterClusterHandlers() {
ps.clusterIFace.RegisterClusterMessageHandler(model.ClusterEventPublish, ps.ClusterPublishHandler)
ps.clusterIFace.RegisterClusterMessageHandler(model.ClusterEventUpdateStatus, ps.ClusterUpdateStatusHandler)
ps.clusterIFace.RegisterClusterMessageHandler(model.ClusterEventInvalidateAllCaches, ps.ClusterInvalidateAllCachesHandler)
ps.clusterIFace.RegisterClusterMessageHandler(model.ClusterEventLoadLicense, ps.LoadLicenseClusterHandler)
ps.clusterIFace.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForChannelMembersNotifyProps, ps.clusterInvalidateCacheForChannelMembersNotifyPropHandler)
ps.clusterIFace.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForChannelByName, ps.clusterInvalidateCacheForChannelByNameHandler)
ps.clusterIFace.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForUser, ps.clusterInvalidateCacheForUserHandler)
@ -155,27 +154,10 @@ func (ps *PlatformService) InvalidateAllCachesSkipSend() {
ps.Store.Webhook().ClearCaches()
linkCache.Purge()
ps.LoadLicense()
}
func (ps *PlatformService) LoadLicenseClusterHandler(_ *model.ClusterMessage) {
ps.loadLicense()
}
func (ps *PlatformService) TriggerLoadLicense() {
ps.loadLicense()
if ps.clusterIFace != nil {
msg := &model.ClusterMessage{
Event: model.ClusterEventLoadLicense,
SendType: model.ClusterSendReliable,
WaitForAllToSend: true,
}
ps.clusterIFace.SendClusterMessage(msg)
}
}
func (ps *PlatformService) InvalidateAllCaches() {
func (ps *PlatformService) InvalidateAllCaches() *model.AppError {
ps.InvalidateAllCachesSkipSend()
if ps.clusterIFace != nil {
@ -188,4 +170,6 @@ func (ps *PlatformService) InvalidateAllCaches() {
ps.clusterIFace.SendClusterMessage(msg)
}
return nil
}

View file

@ -46,7 +46,7 @@ func (ps *PlatformService) License() *model.License {
return ps.licenseValue.Load()
}
func (ps *PlatformService) loadLicense() {
func (ps *PlatformService) LoadLicense() {
// ENV var overrides all other sources of license.
licenseStr := os.Getenv(LicenseEnv)
if licenseStr != "" {
@ -326,6 +326,9 @@ func (ps *PlatformService) RequestTrialLicense(trialRequest *model.TrialLicenseR
return err
}
ps.ReloadConfig()
ps.InvalidateAllCaches()
return nil
}

View file

@ -12,6 +12,14 @@ import (
"github.com/mattermost/mattermost/server/public/model"
)
func TestLoadLicense(t *testing.T) {
th := Setup(t)
defer th.TearDown()
th.Service.LoadLicense()
require.Nil(t, th.Service.License(), "shouldn't have a valid license")
}
func TestSaveLicense(t *testing.T) {
th := Setup(t)
defer th.TearDown()

View file

@ -292,7 +292,7 @@ func New(sc ServiceConfig, options ...Option) (*PlatformService, error) {
// Step 7: Init License
if model.BuildEnterpriseReady == "true" {
ps.TriggerLoadLicense()
ps.LoadLicense()
}
// Step 8: Init Metrics Server depends on step 6 (store) and 7 (license)
@ -353,7 +353,9 @@ func (ps *PlatformService) Start() error {
message := model.NewWebSocketEvent(model.WebsocketEventConfigChanged, "", "", "", nil, "")
message.Add("config", ps.ClientConfigWithComputed())
ps.Publish(message)
ps.Go(func() {
ps.Publish(message)
})
if err := ps.ReconfigureLogger(); err != nil {
mlog.Error("Error re-configuring logging after config change", mlog.Err(err))
@ -366,7 +368,9 @@ func (ps *PlatformService) Start() error {
message := model.NewWebSocketEvent(model.WebsocketEventLicenseChanged, "", "", "", nil, "")
message.Add("license", ps.GetSanitizedClientLicense())
ps.Publish(message)
ps.Go(func() {
ps.Publish(message)
})
})
return nil

View file

@ -209,6 +209,7 @@ func NewServer(options ...Option) (*Server, error) {
// Depends on step 1 (s.Platform must be non-nil)
s.initEnterprise()
// Needed to run before loading license.
s.userService, err = users.New(users.ServiceConfig{
UserStore: s.Store().User(),
SessionStore: s.Store().Session(),
@ -222,6 +223,11 @@ func NewServer(options ...Option) (*Server, error) {
return nil, errors.Wrapf(err, "unable to create users service")
}
if model.BuildEnterpriseReady == "true" {
// Dependent on user service
s.LoadLicense()
}
s.licenseWrapper = &licenseWrapper{
srv: s,
}
@ -1378,6 +1384,8 @@ func (s *Server) sendLicenseUpForRenewalEmail(users map[string]*model.User, lice
}
func (s *Server) doLicenseExpirationCheck() {
s.LoadLicense()
// This takes care of a rare edge case reported here https://mattermost.atlassian.net/browse/MM-40962
// To reproduce that case locally, attach a license to a server that was started with enterprise enabled
// Then restart using BUILD_ENTERPRISE=false make restart-server to enter Team Edition
@ -1387,6 +1395,7 @@ func (s *Server) doLicenseExpirationCheck() {
}
license := s.License()
if license == nil {
mlog.Debug("License cannot be found.")
return

View file

@ -49,6 +49,10 @@ func initDBCommandContext(configDSN string, readOnlyConfigStore bool, options ..
a := app.New(app.ServerConnector(s.Channels()))
if model.BuildEnterpriseReady == "true" {
a.Srv().LoadLicense()
}
return a, nil
}

View file

@ -41,6 +41,8 @@ func jobserverCmdF(command *cobra.Command, args []string) error {
}
defer a.Srv().Shutdown()
a.Srv().LoadLicense()
// Run jobs
mlog.Info("Starting Mattermost job server")
defer mlog.Info("Stopped Mattermost job server")

View file

@ -9,7 +9,6 @@ const (
ClusterEventPublish ClusterEvent = "publish"
ClusterEventUpdateStatus ClusterEvent = "update_status"
ClusterEventInvalidateAllCaches ClusterEvent = "inv_all_caches"
ClusterEventLoadLicense ClusterEvent = "load_license"
ClusterEventInvalidateCacheForReactions ClusterEvent = "inv_reactions"
ClusterEventInvalidateCacheForChannelMembersNotifyProps ClusterEvent = "inv_channel_members_notify_props"
ClusterEventInvalidateCacheForChannelByName ClusterEvent = "inv_channel_name"