This reverts commit dd73c2af0f.
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
01cf4b459f
Коммит
acdfefe456
@@ -319,7 +319,11 @@ func invalidateCaches(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.App.Srv().InvalidateAllCaches()
|
appErr := c.App.Srv().InvalidateAllCaches()
|
||||||
|
if appErr != nil {
|
||||||
|
c.Err = appErr
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
auditRec.Success()
|
auditRec.Success()
|
||||||
|
|
||||||
|
|||||||
@@ -3909,7 +3909,8 @@ func TestLoginWithLag(t *testing.T) {
|
|||||||
_, _, err := th.Client.Login(context.Background(), th.BasicUser.Email, th.BasicUser.Password)
|
_, _, err := th.Client.Login(context.Background(), th.BasicUser.Email, th.BasicUser.Password)
|
||||||
require.NoError(t, err)
|
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)
|
session, appErr := th.App.GetSession(th.Client.AuthToken)
|
||||||
require.Nil(t, appErr)
|
require.Nil(t, appErr)
|
||||||
|
|||||||
@@ -137,8 +137,8 @@ func (a *App) GetClusterStatus() []*model.ClusterInfo {
|
|||||||
return infos
|
return infos
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) InvalidateAllCaches() {
|
func (s *Server) InvalidateAllCaches() *model.AppError {
|
||||||
s.platform.InvalidateAllCaches()
|
return s.platform.InvalidateAllCaches()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) InvalidateAllCachesSkipSend() {
|
func (s *Server) InvalidateAllCachesSkipSend() {
|
||||||
|
|||||||
@@ -131,6 +131,10 @@ func (s *Server) License() *model.License {
|
|||||||
return s.platform.License()
|
return s.platform.License()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) LoadLicense() {
|
||||||
|
s.platform.LoadLicense()
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) SaveLicense(licenseBytes []byte) (*model.License, *model.AppError) {
|
func (s *Server) SaveLicense(licenseBytes []byte) (*model.License, *model.AppError) {
|
||||||
return s.platform.SaveLicense(licenseBytes)
|
return s.platform.SaveLicense(licenseBytes)
|
||||||
}
|
}
|
||||||
|
|||||||
109
server/channels/app/license_test.go
Обычный файл
109
server/channels/app/license_test.go
Обычный файл
@@ -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)
|
||||||
|
}
|
||||||
@@ -99,7 +99,8 @@ func TestSendNotifications(t *testing.T) {
|
|||||||
|
|
||||||
_, appErr = th.App.UpdateActive(th.Context, th.BasicUser2, false)
|
_, appErr = th.App.UpdateActive(th.Context, th.BasicUser2, false)
|
||||||
require.Nil(t, appErr)
|
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{
|
post3, appErr := th.App.CreatePostMissingChannel(th.Context, &model.Post{
|
||||||
UserId: th.BasicUser.Id,
|
UserId: th.BasicUser.Id,
|
||||||
|
|||||||
@@ -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)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ func (ps *PlatformService) RegisterClusterHandlers() {
|
|||||||
ps.clusterIFace.RegisterClusterMessageHandler(model.ClusterEventPublish, ps.ClusterPublishHandler)
|
ps.clusterIFace.RegisterClusterMessageHandler(model.ClusterEventPublish, ps.ClusterPublishHandler)
|
||||||
ps.clusterIFace.RegisterClusterMessageHandler(model.ClusterEventUpdateStatus, ps.ClusterUpdateStatusHandler)
|
ps.clusterIFace.RegisterClusterMessageHandler(model.ClusterEventUpdateStatus, ps.ClusterUpdateStatusHandler)
|
||||||
ps.clusterIFace.RegisterClusterMessageHandler(model.ClusterEventInvalidateAllCaches, ps.ClusterInvalidateAllCachesHandler)
|
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.ClusterEventInvalidateCacheForChannelMembersNotifyProps, ps.clusterInvalidateCacheForChannelMembersNotifyPropHandler)
|
||||||
ps.clusterIFace.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForChannelByName, ps.clusterInvalidateCacheForChannelByNameHandler)
|
ps.clusterIFace.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForChannelByName, ps.clusterInvalidateCacheForChannelByNameHandler)
|
||||||
ps.clusterIFace.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForUser, ps.clusterInvalidateCacheForUserHandler)
|
ps.clusterIFace.RegisterClusterMessageHandler(model.ClusterEventInvalidateCacheForUser, ps.clusterInvalidateCacheForUserHandler)
|
||||||
@@ -155,27 +154,10 @@ func (ps *PlatformService) InvalidateAllCachesSkipSend() {
|
|||||||
ps.Store.Webhook().ClearCaches()
|
ps.Store.Webhook().ClearCaches()
|
||||||
|
|
||||||
linkCache.Purge()
|
linkCache.Purge()
|
||||||
|
ps.LoadLicense()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ps *PlatformService) LoadLicenseClusterHandler(_ *model.ClusterMessage) {
|
func (ps *PlatformService) InvalidateAllCaches() *model.AppError {
|
||||||
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() {
|
|
||||||
ps.InvalidateAllCachesSkipSend()
|
ps.InvalidateAllCachesSkipSend()
|
||||||
|
|
||||||
if ps.clusterIFace != nil {
|
if ps.clusterIFace != nil {
|
||||||
@@ -188,4 +170,6 @@ func (ps *PlatformService) InvalidateAllCaches() {
|
|||||||
|
|
||||||
ps.clusterIFace.SendClusterMessage(msg)
|
ps.clusterIFace.SendClusterMessage(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ func (ps *PlatformService) License() *model.License {
|
|||||||
return ps.licenseValue.Load()
|
return ps.licenseValue.Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ps *PlatformService) loadLicense() {
|
func (ps *PlatformService) LoadLicense() {
|
||||||
// ENV var overrides all other sources of license.
|
// ENV var overrides all other sources of license.
|
||||||
licenseStr := os.Getenv(LicenseEnv)
|
licenseStr := os.Getenv(LicenseEnv)
|
||||||
if licenseStr != "" {
|
if licenseStr != "" {
|
||||||
@@ -326,6 +326,9 @@ func (ps *PlatformService) RequestTrialLicense(trialRequest *model.TrialLicenseR
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ps.ReloadConfig()
|
||||||
|
ps.InvalidateAllCaches()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,14 @@ import (
|
|||||||
"github.com/mattermost/mattermost/server/public/model"
|
"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) {
|
func TestSaveLicense(t *testing.T) {
|
||||||
th := Setup(t)
|
th := Setup(t)
|
||||||
defer th.TearDown()
|
defer th.TearDown()
|
||||||
|
|||||||
@@ -292,7 +292,7 @@ func New(sc ServiceConfig, options ...Option) (*PlatformService, error) {
|
|||||||
|
|
||||||
// Step 7: Init License
|
// Step 7: Init License
|
||||||
if model.BuildEnterpriseReady == "true" {
|
if model.BuildEnterpriseReady == "true" {
|
||||||
ps.TriggerLoadLicense()
|
ps.LoadLicense()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 8: Init Metrics Server depends on step 6 (store) and 7 (license)
|
// 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 := model.NewWebSocketEvent(model.WebsocketEventConfigChanged, "", "", "", nil, "")
|
||||||
|
|
||||||
message.Add("config", ps.ClientConfigWithComputed())
|
message.Add("config", ps.ClientConfigWithComputed())
|
||||||
ps.Publish(message)
|
ps.Go(func() {
|
||||||
|
ps.Publish(message)
|
||||||
|
})
|
||||||
|
|
||||||
if err := ps.ReconfigureLogger(); err != nil {
|
if err := ps.ReconfigureLogger(); err != nil {
|
||||||
mlog.Error("Error re-configuring logging after config change", mlog.Err(err))
|
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 := model.NewWebSocketEvent(model.WebsocketEventLicenseChanged, "", "", "", nil, "")
|
||||||
message.Add("license", ps.GetSanitizedClientLicense())
|
message.Add("license", ps.GetSanitizedClientLicense())
|
||||||
ps.Publish(message)
|
ps.Go(func() {
|
||||||
|
ps.Publish(message)
|
||||||
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -209,6 +209,7 @@ func NewServer(options ...Option) (*Server, error) {
|
|||||||
// Depends on step 1 (s.Platform must be non-nil)
|
// Depends on step 1 (s.Platform must be non-nil)
|
||||||
s.initEnterprise()
|
s.initEnterprise()
|
||||||
|
|
||||||
|
// Needed to run before loading license.
|
||||||
s.userService, err = users.New(users.ServiceConfig{
|
s.userService, err = users.New(users.ServiceConfig{
|
||||||
UserStore: s.Store().User(),
|
UserStore: s.Store().User(),
|
||||||
SessionStore: s.Store().Session(),
|
SessionStore: s.Store().Session(),
|
||||||
@@ -222,6 +223,11 @@ func NewServer(options ...Option) (*Server, error) {
|
|||||||
return nil, errors.Wrapf(err, "unable to create users service")
|
return nil, errors.Wrapf(err, "unable to create users service")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if model.BuildEnterpriseReady == "true" {
|
||||||
|
// Dependent on user service
|
||||||
|
s.LoadLicense()
|
||||||
|
}
|
||||||
|
|
||||||
s.licenseWrapper = &licenseWrapper{
|
s.licenseWrapper = &licenseWrapper{
|
||||||
srv: s,
|
srv: s,
|
||||||
}
|
}
|
||||||
@@ -1378,6 +1384,8 @@ func (s *Server) sendLicenseUpForRenewalEmail(users map[string]*model.User, lice
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) doLicenseExpirationCheck() {
|
func (s *Server) doLicenseExpirationCheck() {
|
||||||
|
s.LoadLicense()
|
||||||
|
|
||||||
// This takes care of a rare edge case reported here https://mattermost.atlassian.net/browse/MM-40962
|
// 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
|
// 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
|
// Then restart using BUILD_ENTERPRISE=false make restart-server to enter Team Edition
|
||||||
@@ -1387,6 +1395,7 @@ func (s *Server) doLicenseExpirationCheck() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
license := s.License()
|
license := s.License()
|
||||||
|
|
||||||
if license == nil {
|
if license == nil {
|
||||||
mlog.Debug("License cannot be found.")
|
mlog.Debug("License cannot be found.")
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -49,6 +49,10 @@ func initDBCommandContext(configDSN string, readOnlyConfigStore bool, options ..
|
|||||||
|
|
||||||
a := app.New(app.ServerConnector(s.Channels()))
|
a := app.New(app.ServerConnector(s.Channels()))
|
||||||
|
|
||||||
|
if model.BuildEnterpriseReady == "true" {
|
||||||
|
a.Srv().LoadLicense()
|
||||||
|
}
|
||||||
|
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ func jobserverCmdF(command *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
defer a.Srv().Shutdown()
|
defer a.Srv().Shutdown()
|
||||||
|
|
||||||
|
a.Srv().LoadLicense()
|
||||||
|
|
||||||
// Run jobs
|
// Run jobs
|
||||||
mlog.Info("Starting Mattermost job server")
|
mlog.Info("Starting Mattermost job server")
|
||||||
defer mlog.Info("Stopped Mattermost job server")
|
defer mlog.Info("Stopped Mattermost job server")
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ const (
|
|||||||
ClusterEventPublish ClusterEvent = "publish"
|
ClusterEventPublish ClusterEvent = "publish"
|
||||||
ClusterEventUpdateStatus ClusterEvent = "update_status"
|
ClusterEventUpdateStatus ClusterEvent = "update_status"
|
||||||
ClusterEventInvalidateAllCaches ClusterEvent = "inv_all_caches"
|
ClusterEventInvalidateAllCaches ClusterEvent = "inv_all_caches"
|
||||||
ClusterEventLoadLicense ClusterEvent = "load_license"
|
|
||||||
ClusterEventInvalidateCacheForReactions ClusterEvent = "inv_reactions"
|
ClusterEventInvalidateCacheForReactions ClusterEvent = "inv_reactions"
|
||||||
ClusterEventInvalidateCacheForChannelMembersNotifyProps ClusterEvent = "inv_channel_members_notify_props"
|
ClusterEventInvalidateCacheForChannelMembersNotifyProps ClusterEvent = "inv_channel_members_notify_props"
|
||||||
ClusterEventInvalidateCacheForChannelByName ClusterEvent = "inv_channel_name"
|
ClusterEventInvalidateCacheForChannelByName ClusterEvent = "inv_channel_name"
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user