Move some more atomic values under Channels (#18837)
* Move some more atomic values under Channels The following fields were moved: ``` asymmetricSigningKey atomic.Value clientConfig atomic.Value clientConfigHash atomic.Value limitedClientConfig atomic.Value ``` And also moved the initialization order from NewServer to Channels.Start to better reflect the order of things. Removed AsymmetricSigningKey from ConfigService as it was no longer used. Removed calling regenerateClientConfig during startup explicitly because it was anyways called from ensureAsymmetricSigningKey. https://community-daily.mattermost.com/boards/workspace/zyoahc9uapdn3xdptac6jb69ic/285b80a3-257d-41f6-8cf4-ed80ca9d92e5/495cdb4d-c13a-4992-8eb9-80cfee2819a4?c=87df1e15-588e-49ff-8bd1-ffa9651b8c82 ```release-note NONE ``` * Fix lint error ```release-note NONE ```
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
a499d2f378
Коммит
6bc6243131
@@ -4,8 +4,11 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"sync/atomic"
|
||||||
|
|
||||||
"github.com/mattermost/mattermost-server/v6/model"
|
"github.com/mattermost/mattermost-server/v6/model"
|
||||||
"github.com/mattermost/mattermost-server/v6/services/imageproxy"
|
"github.com/mattermost/mattermost-server/v6/services/imageproxy"
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Channels contains all channels related state.
|
// Channels contains all channels related state.
|
||||||
@@ -14,6 +17,11 @@ type Channels struct {
|
|||||||
|
|
||||||
imageProxy *imageproxy.ImageProxy
|
imageProxy *imageproxy.ImageProxy
|
||||||
|
|
||||||
|
asymmetricSigningKey atomic.Value
|
||||||
|
clientConfig atomic.Value
|
||||||
|
clientConfigHash atomic.Value
|
||||||
|
limitedClientConfig atomic.Value
|
||||||
|
|
||||||
// cached counts that are used during notice condition validation
|
// cached counts that are used during notice condition validation
|
||||||
cachedPostCount int64
|
cachedPostCount int64
|
||||||
cachedUserCount int64
|
cachedUserCount int64
|
||||||
@@ -35,10 +43,13 @@ func NewChannels(s *Server) (*Channels, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Channels) Start() error {
|
func (ch *Channels) Start() error {
|
||||||
|
if err := ch.ensureAsymmetricSigningKey(); err != nil {
|
||||||
|
return errors.Wrapf(err, "unable to ensure asymmetric signing key")
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Channels) Stop() error {
|
func (*Channels) Stop() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,15 +75,15 @@ func (a *App) ReloadConfig() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) ClientConfig() map[string]string {
|
func (a *App) ClientConfig() map[string]string {
|
||||||
return a.Srv().clientConfig.Load().(map[string]string)
|
return a.ch.clientConfig.Load().(map[string]string)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) ClientConfigHash() string {
|
func (a *App) ClientConfigHash() string {
|
||||||
return a.Srv().ClientConfigHash()
|
return a.ch.ClientConfigHash()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) LimitedClientConfig() map[string]string {
|
func (a *App) LimitedClientConfig() map[string]string {
|
||||||
return a.Srv().limitedClientConfig.Load().(map[string]string)
|
return a.ch.limitedClientConfig.Load().(map[string]string)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Registers a function with a given listener to be called when the config is reloaded and may have changed. The function
|
// Registers a function with a given listener to be called when the config is reloaded and may have changed. The function
|
||||||
@@ -168,14 +168,14 @@ func (s *Server) ensurePostActionCookieSecret() error {
|
|||||||
|
|
||||||
// ensureAsymmetricSigningKey ensures that an asymmetric signing key exists and future calls to
|
// ensureAsymmetricSigningKey ensures that an asymmetric signing key exists and future calls to
|
||||||
// AsymmetricSigningKey will always return a valid signing key.
|
// AsymmetricSigningKey will always return a valid signing key.
|
||||||
func (s *Server) ensureAsymmetricSigningKey() error {
|
func (ch *Channels) ensureAsymmetricSigningKey() error {
|
||||||
if s.AsymmetricSigningKey() != nil {
|
if ch.AsymmetricSigningKey() != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var key *model.SystemAsymmetricSigningKey
|
var key *model.SystemAsymmetricSigningKey
|
||||||
|
|
||||||
value, err := s.Store.System().GetByName(model.SystemAsymmetricSigningKeyKey)
|
value, err := ch.srv.Store.System().GetByName(model.SystemAsymmetricSigningKeyKey)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if err := json.Unmarshal([]byte(value.Value), &key); err != nil {
|
if err := json.Unmarshal([]byte(value.Value), &key); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -205,7 +205,7 @@ func (s *Server) ensureAsymmetricSigningKey() error {
|
|||||||
}
|
}
|
||||||
system.Value = string(v)
|
system.Value = string(v)
|
||||||
// If we were able to save the key, use it, otherwise log the error.
|
// If we were able to save the key, use it, otherwise log the error.
|
||||||
if err = s.Store.System().Save(system); err != nil {
|
if err = ch.srv.Store.System().Save(system); err != nil {
|
||||||
mlog.Warn("Failed to save AsymmetricSigningKey", mlog.Err(err))
|
mlog.Warn("Failed to save AsymmetricSigningKey", mlog.Err(err))
|
||||||
} else {
|
} else {
|
||||||
key = newKey
|
key = newKey
|
||||||
@@ -215,7 +215,7 @@ func (s *Server) ensureAsymmetricSigningKey() error {
|
|||||||
// If we weren't able to save a new key above, another server must have beat us to it. Get the
|
// If we weren't able to save a new key above, another server must have beat us to it. Get the
|
||||||
// key from the database, and if that fails, error out.
|
// key from the database, and if that fails, error out.
|
||||||
if key == nil {
|
if key == nil {
|
||||||
value, err := s.Store.System().GetByName(model.SystemAsymmetricSigningKeyKey)
|
value, err := ch.srv.Store.System().GetByName(model.SystemAsymmetricSigningKeyKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -232,7 +232,7 @@ func (s *Server) ensureAsymmetricSigningKey() error {
|
|||||||
default:
|
default:
|
||||||
return fmt.Errorf("unknown curve: " + key.ECDSAKey.Curve)
|
return fmt.Errorf("unknown curve: " + key.ECDSAKey.Curve)
|
||||||
}
|
}
|
||||||
s.asymmetricSigningKey.Store(&ecdsa.PrivateKey{
|
ch.asymmetricSigningKey.Store(&ecdsa.PrivateKey{
|
||||||
PublicKey: ecdsa.PublicKey{
|
PublicKey: ecdsa.PublicKey{
|
||||||
Curve: curve,
|
Curve: curve,
|
||||||
X: key.ECDSAKey.X,
|
X: key.ECDSAKey.X,
|
||||||
@@ -240,7 +240,7 @@ func (s *Server) ensureAsymmetricSigningKey() error {
|
|||||||
},
|
},
|
||||||
D: key.ECDSAKey.D,
|
D: key.ECDSAKey.D,
|
||||||
})
|
})
|
||||||
s.regenerateClientConfig()
|
ch.regenerateClientConfig()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,15 +283,15 @@ func (s *Server) ensureFirstServerRunTimestamp() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AsymmetricSigningKey will return a private key that can be used for asymmetric signing.
|
// AsymmetricSigningKey will return a private key that can be used for asymmetric signing.
|
||||||
func (s *Server) AsymmetricSigningKey() *ecdsa.PrivateKey {
|
func (ch *Channels) AsymmetricSigningKey() *ecdsa.PrivateKey {
|
||||||
if key := s.asymmetricSigningKey.Load(); key != nil {
|
if key := ch.asymmetricSigningKey.Load(); key != nil {
|
||||||
return key.(*ecdsa.PrivateKey)
|
return key.(*ecdsa.PrivateKey)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) AsymmetricSigningKey() *ecdsa.PrivateKey {
|
func (a *App) AsymmetricSigningKey() *ecdsa.PrivateKey {
|
||||||
return a.Srv().AsymmetricSigningKey()
|
return a.ch.AsymmetricSigningKey()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) PostActionCookieSecret() []byte {
|
func (s *Server) PostActionCookieSecret() []byte {
|
||||||
@@ -302,12 +302,12 @@ func (a *App) PostActionCookieSecret() []byte {
|
|||||||
return a.Srv().PostActionCookieSecret()
|
return a.Srv().PostActionCookieSecret()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) regenerateClientConfig() {
|
func (ch *Channels) regenerateClientConfig() {
|
||||||
clientConfig := config.GenerateClientConfig(s.Config(), s.TelemetryId(), s.License())
|
clientConfig := config.GenerateClientConfig(ch.srv.Config(), ch.srv.TelemetryId(), ch.srv.License())
|
||||||
limitedClientConfig := config.GenerateLimitedClientConfig(s.Config(), s.TelemetryId(), s.License())
|
limitedClientConfig := config.GenerateLimitedClientConfig(ch.srv.Config(), ch.srv.TelemetryId(), ch.srv.License())
|
||||||
|
|
||||||
if clientConfig["EnableCustomTermsOfService"] == "true" {
|
if clientConfig["EnableCustomTermsOfService"] == "true" {
|
||||||
termsOfService, err := s.Store.TermsOfService().GetLatest(true)
|
termsOfService, err := ch.srv.Store.TermsOfService().GetLatest(true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
mlog.Err(err)
|
mlog.Err(err)
|
||||||
} else {
|
} else {
|
||||||
@@ -316,16 +316,16 @@ func (s *Server) regenerateClientConfig() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if key := s.AsymmetricSigningKey(); key != nil {
|
if key := ch.AsymmetricSigningKey(); key != nil {
|
||||||
der, _ := x509.MarshalPKIXPublicKey(&key.PublicKey)
|
der, _ := x509.MarshalPKIXPublicKey(&key.PublicKey)
|
||||||
clientConfig["AsymmetricSigningPublicKey"] = base64.StdEncoding.EncodeToString(der)
|
clientConfig["AsymmetricSigningPublicKey"] = base64.StdEncoding.EncodeToString(der)
|
||||||
limitedClientConfig["AsymmetricSigningPublicKey"] = base64.StdEncoding.EncodeToString(der)
|
limitedClientConfig["AsymmetricSigningPublicKey"] = base64.StdEncoding.EncodeToString(der)
|
||||||
}
|
}
|
||||||
|
|
||||||
clientConfigJSON, _ := json.Marshal(clientConfig)
|
clientConfigJSON, _ := json.Marshal(clientConfig)
|
||||||
s.clientConfig.Store(clientConfig)
|
ch.clientConfig.Store(clientConfig)
|
||||||
s.limitedClientConfig.Store(limitedClientConfig)
|
ch.limitedClientConfig.Store(limitedClientConfig)
|
||||||
s.clientConfigHash.Store(fmt.Sprintf("%x", md5.Sum(clientConfigJSON)))
|
ch.clientConfigHash.Store(fmt.Sprintf("%x", md5.Sum(clientConfigJSON)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) GetCookieDomain() string {
|
func (a *App) GetCookieDomain() string {
|
||||||
@@ -342,30 +342,25 @@ func (a *App) GetSiteURL() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ClientConfigWithComputed gets the configuration in a format suitable for sending to the client.
|
// ClientConfigWithComputed gets the configuration in a format suitable for sending to the client.
|
||||||
func (s *Server) ClientConfigWithComputed() map[string]string {
|
func (a *App) ClientConfigWithComputed() map[string]string {
|
||||||
respCfg := map[string]string{}
|
respCfg := map[string]string{}
|
||||||
for k, v := range s.clientConfig.Load().(map[string]string) {
|
for k, v := range a.ch.clientConfig.Load().(map[string]string) {
|
||||||
respCfg[k] = v
|
respCfg[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
// These properties are not configurable, but nevertheless represent configuration expected
|
// These properties are not configurable, but nevertheless represent configuration expected
|
||||||
// by the client.
|
// by the client.
|
||||||
respCfg["NoAccounts"] = strconv.FormatBool(s.userService.IsFirstUserAccount())
|
respCfg["NoAccounts"] = strconv.FormatBool(a.ch.srv.userService.IsFirstUserAccount())
|
||||||
respCfg["MaxPostSize"] = strconv.Itoa(s.MaxPostSize())
|
respCfg["MaxPostSize"] = strconv.Itoa(a.ch.srv.MaxPostSize())
|
||||||
respCfg["UpgradedFromTE"] = strconv.FormatBool(s.isUpgradedFromTE())
|
respCfg["UpgradedFromTE"] = strconv.FormatBool(a.ch.srv.isUpgradedFromTE())
|
||||||
respCfg["InstallationDate"] = ""
|
respCfg["InstallationDate"] = ""
|
||||||
if installationDate, err := s.getSystemInstallDate(); err == nil {
|
if installationDate, err := a.ch.srv.getSystemInstallDate(); err == nil {
|
||||||
respCfg["InstallationDate"] = strconv.FormatInt(installationDate, 10)
|
respCfg["InstallationDate"] = strconv.FormatInt(installationDate, 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
return respCfg
|
return respCfg
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClientConfigWithComputed gets the configuration in a format suitable for sending to the client.
|
|
||||||
func (a *App) ClientConfigWithComputed() map[string]string {
|
|
||||||
return a.Srv().ClientConfigWithComputed()
|
|
||||||
}
|
|
||||||
|
|
||||||
// LimitedClientConfigWithComputed gets the configuration in a format suitable for sending to the client.
|
// LimitedClientConfigWithComputed gets the configuration in a format suitable for sending to the client.
|
||||||
func (a *App) LimitedClientConfigWithComputed() map[string]string {
|
func (a *App) LimitedClientConfigWithComputed() map[string]string {
|
||||||
respCfg := map[string]string{}
|
respCfg := map[string]string{}
|
||||||
|
|||||||
@@ -150,11 +150,6 @@ type Server struct {
|
|||||||
pluginCommands []*PluginCommand
|
pluginCommands []*PluginCommand
|
||||||
pluginCommandsLock sync.RWMutex
|
pluginCommandsLock sync.RWMutex
|
||||||
|
|
||||||
asymmetricSigningKey atomic.Value
|
|
||||||
clientConfig atomic.Value
|
|
||||||
clientConfigHash atomic.Value
|
|
||||||
limitedClientConfig atomic.Value
|
|
||||||
|
|
||||||
telemetryService *telemetry.TelemetryService
|
telemetryService *telemetry.TelemetryService
|
||||||
userService *users.UserService
|
userService *users.UserService
|
||||||
teamService *teams.TeamService
|
teamService *teams.TeamService
|
||||||
@@ -447,17 +442,19 @@ func NewServer(options ...Option) (*Server, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
s.configListenerId = s.AddConfigListener(func(_, _ *model.Config) {
|
s.configListenerId = s.AddConfigListener(func(_, _ *model.Config) {
|
||||||
s.configOrLicenseListener()
|
ch := s.Channels()
|
||||||
|
ch.regenerateClientConfig()
|
||||||
|
|
||||||
message := model.NewWebSocketEvent(model.WebsocketEventConfigChanged, "", "", "", nil)
|
message := model.NewWebSocketEvent(model.WebsocketEventConfigChanged, "", "", "", nil)
|
||||||
|
|
||||||
message.Add("config", s.ClientConfigWithComputed())
|
appInstance := New(ServerConnector(ch))
|
||||||
|
message.Add("config", appInstance.ClientConfigWithComputed())
|
||||||
s.Go(func() {
|
s.Go(func() {
|
||||||
s.Publish(message)
|
s.Publish(message)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
s.licenseListenerId = s.AddLicenseListener(func(oldLicense, newLicense *model.License) {
|
s.licenseListenerId = s.AddLicenseListener(func(oldLicense, newLicense *model.License) {
|
||||||
s.configOrLicenseListener()
|
s.Channels().regenerateClientConfig()
|
||||||
|
|
||||||
message := model.NewWebSocketEvent(model.WebsocketEventLicenseChanged, "", "", "", nil)
|
message := model.NewWebSocketEvent(model.WebsocketEventLicenseChanged, "", "", "", nil)
|
||||||
message.Add("license", s.GetSanitizedClientLicense())
|
message.Add("license", s.GetSanitizedClientLicense())
|
||||||
@@ -503,10 +500,6 @@ func NewServer(options ...Option) (*Server, error) {
|
|||||||
s.Cluster.StartInterNodeCommunication()
|
s.Cluster.StartInterNodeCommunication()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = s.ensureAsymmetricSigningKey(); err != nil {
|
|
||||||
return nil, errors.Wrapf(err, "unable to ensure asymmetric signing key")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = s.ensurePostActionCookieSecret(); err != nil {
|
if err = s.ensurePostActionCookieSecret(); err != nil {
|
||||||
return nil, errors.Wrapf(err, "unable to ensure PostAction cookie secret")
|
return nil, errors.Wrapf(err, "unable to ensure PostAction cookie secret")
|
||||||
}
|
}
|
||||||
@@ -519,8 +512,6 @@ func NewServer(options ...Option) (*Server, error) {
|
|||||||
return nil, errors.Wrapf(err, "unable to ensure first run timestamp")
|
return nil, errors.Wrapf(err, "unable to ensure first run timestamp")
|
||||||
}
|
}
|
||||||
|
|
||||||
s.regenerateClientConfig()
|
|
||||||
|
|
||||||
subpath, err := utils.GetSubpathFromConfig(s.Config())
|
subpath, err := utils.GetSubpathFromConfig(s.Config())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to parse SiteURL subpath")
|
return nil, errors.Wrap(err, "failed to parse SiteURL subpath")
|
||||||
@@ -1914,12 +1905,8 @@ func (s *Server) ClusterHealthScore() int {
|
|||||||
return s.Cluster.HealthScore()
|
return s.Cluster.HealthScore()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) configOrLicenseListener() {
|
func (ch *Channels) ClientConfigHash() string {
|
||||||
s.regenerateClientConfig()
|
return ch.clientConfigHash.Load().(string)
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) ClientConfigHash() string {
|
|
||||||
return s.clientConfigHash.Load().(string)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) initJobs() {
|
func (s *Server) initJobs() {
|
||||||
|
|||||||
@@ -4,8 +4,6 @@
|
|||||||
package configservice
|
package configservice
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/ecdsa"
|
|
||||||
|
|
||||||
"github.com/mattermost/mattermost-server/v6/model"
|
"github.com/mattermost/mattermost-server/v6/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -14,5 +12,4 @@ type ConfigService interface {
|
|||||||
Config() *model.Config
|
Config() *model.Config
|
||||||
AddConfigListener(func(old, current *model.Config)) string
|
AddConfigListener(func(old, current *model.Config)) string
|
||||||
RemoveConfigListener(string)
|
RemoveConfigListener(string)
|
||||||
AsymmetricSigningKey() *ecdsa.PrivateKey
|
|
||||||
}
|
}
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user