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
|
||||
|
||||
import (
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/services/imageproxy"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Channels contains all channels related state.
|
||||
@@ -14,6 +17,11 @@ type Channels struct {
|
||||
|
||||
imageProxy *imageproxy.ImageProxy
|
||||
|
||||
asymmetricSigningKey atomic.Value
|
||||
clientConfig atomic.Value
|
||||
clientConfigHash atomic.Value
|
||||
limitedClientConfig atomic.Value
|
||||
|
||||
// cached counts that are used during notice condition validation
|
||||
cachedPostCount int64
|
||||
cachedUserCount int64
|
||||
@@ -35,10 +43,13 @@ func NewChannels(s *Server) (*Channels, error) {
|
||||
}, 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
|
||||
}
|
||||
|
||||
func (c *Channels) Stop() error {
|
||||
func (*Channels) Stop() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -75,15 +75,15 @@ func (a *App) ReloadConfig() error {
|
||||
}
|
||||
|
||||
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 {
|
||||
return a.Srv().ClientConfigHash()
|
||||
return a.ch.ClientConfigHash()
|
||||
}
|
||||
|
||||
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
|
||||
@@ -168,14 +168,14 @@ func (s *Server) ensurePostActionCookieSecret() error {
|
||||
|
||||
// ensureAsymmetricSigningKey ensures that an asymmetric signing key exists and future calls to
|
||||
// AsymmetricSigningKey will always return a valid signing key.
|
||||
func (s *Server) ensureAsymmetricSigningKey() error {
|
||||
if s.AsymmetricSigningKey() != nil {
|
||||
func (ch *Channels) ensureAsymmetricSigningKey() error {
|
||||
if ch.AsymmetricSigningKey() != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
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 := json.Unmarshal([]byte(value.Value), &key); err != nil {
|
||||
return err
|
||||
@@ -205,7 +205,7 @@ func (s *Server) ensureAsymmetricSigningKey() error {
|
||||
}
|
||||
system.Value = string(v)
|
||||
// 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))
|
||||
} else {
|
||||
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
|
||||
// key from the database, and if that fails, error out.
|
||||
if key == nil {
|
||||
value, err := s.Store.System().GetByName(model.SystemAsymmetricSigningKeyKey)
|
||||
value, err := ch.srv.Store.System().GetByName(model.SystemAsymmetricSigningKeyKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -232,7 +232,7 @@ func (s *Server) ensureAsymmetricSigningKey() error {
|
||||
default:
|
||||
return fmt.Errorf("unknown curve: " + key.ECDSAKey.Curve)
|
||||
}
|
||||
s.asymmetricSigningKey.Store(&ecdsa.PrivateKey{
|
||||
ch.asymmetricSigningKey.Store(&ecdsa.PrivateKey{
|
||||
PublicKey: ecdsa.PublicKey{
|
||||
Curve: curve,
|
||||
X: key.ECDSAKey.X,
|
||||
@@ -240,7 +240,7 @@ func (s *Server) ensureAsymmetricSigningKey() error {
|
||||
},
|
||||
D: key.ECDSAKey.D,
|
||||
})
|
||||
s.regenerateClientConfig()
|
||||
ch.regenerateClientConfig()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -283,15 +283,15 @@ func (s *Server) ensureFirstServerRunTimestamp() error {
|
||||
}
|
||||
|
||||
// AsymmetricSigningKey will return a private key that can be used for asymmetric signing.
|
||||
func (s *Server) AsymmetricSigningKey() *ecdsa.PrivateKey {
|
||||
if key := s.asymmetricSigningKey.Load(); key != nil {
|
||||
func (ch *Channels) AsymmetricSigningKey() *ecdsa.PrivateKey {
|
||||
if key := ch.asymmetricSigningKey.Load(); key != nil {
|
||||
return key.(*ecdsa.PrivateKey)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *App) AsymmetricSigningKey() *ecdsa.PrivateKey {
|
||||
return a.Srv().AsymmetricSigningKey()
|
||||
return a.ch.AsymmetricSigningKey()
|
||||
}
|
||||
|
||||
func (s *Server) PostActionCookieSecret() []byte {
|
||||
@@ -302,12 +302,12 @@ func (a *App) PostActionCookieSecret() []byte {
|
||||
return a.Srv().PostActionCookieSecret()
|
||||
}
|
||||
|
||||
func (s *Server) regenerateClientConfig() {
|
||||
clientConfig := config.GenerateClientConfig(s.Config(), s.TelemetryId(), s.License())
|
||||
limitedClientConfig := config.GenerateLimitedClientConfig(s.Config(), s.TelemetryId(), s.License())
|
||||
func (ch *Channels) regenerateClientConfig() {
|
||||
clientConfig := config.GenerateClientConfig(ch.srv.Config(), ch.srv.TelemetryId(), ch.srv.License())
|
||||
limitedClientConfig := config.GenerateLimitedClientConfig(ch.srv.Config(), ch.srv.TelemetryId(), ch.srv.License())
|
||||
|
||||
if clientConfig["EnableCustomTermsOfService"] == "true" {
|
||||
termsOfService, err := s.Store.TermsOfService().GetLatest(true)
|
||||
termsOfService, err := ch.srv.Store.TermsOfService().GetLatest(true)
|
||||
if err != nil {
|
||||
mlog.Err(err)
|
||||
} 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)
|
||||
clientConfig["AsymmetricSigningPublicKey"] = base64.StdEncoding.EncodeToString(der)
|
||||
limitedClientConfig["AsymmetricSigningPublicKey"] = base64.StdEncoding.EncodeToString(der)
|
||||
}
|
||||
|
||||
clientConfigJSON, _ := json.Marshal(clientConfig)
|
||||
s.clientConfig.Store(clientConfig)
|
||||
s.limitedClientConfig.Store(limitedClientConfig)
|
||||
s.clientConfigHash.Store(fmt.Sprintf("%x", md5.Sum(clientConfigJSON)))
|
||||
ch.clientConfig.Store(clientConfig)
|
||||
ch.limitedClientConfig.Store(limitedClientConfig)
|
||||
ch.clientConfigHash.Store(fmt.Sprintf("%x", md5.Sum(clientConfigJSON)))
|
||||
}
|
||||
|
||||
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.
|
||||
func (s *Server) ClientConfigWithComputed() map[string]string {
|
||||
func (a *App) ClientConfigWithComputed() 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
|
||||
}
|
||||
|
||||
// These properties are not configurable, but nevertheless represent configuration expected
|
||||
// by the client.
|
||||
respCfg["NoAccounts"] = strconv.FormatBool(s.userService.IsFirstUserAccount())
|
||||
respCfg["MaxPostSize"] = strconv.Itoa(s.MaxPostSize())
|
||||
respCfg["UpgradedFromTE"] = strconv.FormatBool(s.isUpgradedFromTE())
|
||||
respCfg["NoAccounts"] = strconv.FormatBool(a.ch.srv.userService.IsFirstUserAccount())
|
||||
respCfg["MaxPostSize"] = strconv.Itoa(a.ch.srv.MaxPostSize())
|
||||
respCfg["UpgradedFromTE"] = strconv.FormatBool(a.ch.srv.isUpgradedFromTE())
|
||||
respCfg["InstallationDate"] = ""
|
||||
if installationDate, err := s.getSystemInstallDate(); err == nil {
|
||||
if installationDate, err := a.ch.srv.getSystemInstallDate(); err == nil {
|
||||
respCfg["InstallationDate"] = strconv.FormatInt(installationDate, 10)
|
||||
}
|
||||
|
||||
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.
|
||||
func (a *App) LimitedClientConfigWithComputed() map[string]string {
|
||||
respCfg := map[string]string{}
|
||||
|
||||
@@ -150,11 +150,6 @@ type Server struct {
|
||||
pluginCommands []*PluginCommand
|
||||
pluginCommandsLock sync.RWMutex
|
||||
|
||||
asymmetricSigningKey atomic.Value
|
||||
clientConfig atomic.Value
|
||||
clientConfigHash atomic.Value
|
||||
limitedClientConfig atomic.Value
|
||||
|
||||
telemetryService *telemetry.TelemetryService
|
||||
userService *users.UserService
|
||||
teamService *teams.TeamService
|
||||
@@ -447,17 +442,19 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
}
|
||||
|
||||
s.configListenerId = s.AddConfigListener(func(_, _ *model.Config) {
|
||||
s.configOrLicenseListener()
|
||||
ch := s.Channels()
|
||||
ch.regenerateClientConfig()
|
||||
|
||||
message := model.NewWebSocketEvent(model.WebsocketEventConfigChanged, "", "", "", nil)
|
||||
|
||||
message.Add("config", s.ClientConfigWithComputed())
|
||||
appInstance := New(ServerConnector(ch))
|
||||
message.Add("config", appInstance.ClientConfigWithComputed())
|
||||
s.Go(func() {
|
||||
s.Publish(message)
|
||||
})
|
||||
})
|
||||
s.licenseListenerId = s.AddLicenseListener(func(oldLicense, newLicense *model.License) {
|
||||
s.configOrLicenseListener()
|
||||
s.Channels().regenerateClientConfig()
|
||||
|
||||
message := model.NewWebSocketEvent(model.WebsocketEventLicenseChanged, "", "", "", nil)
|
||||
message.Add("license", s.GetSanitizedClientLicense())
|
||||
@@ -503,10 +500,6 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
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 {
|
||||
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")
|
||||
}
|
||||
|
||||
s.regenerateClientConfig()
|
||||
|
||||
subpath, err := utils.GetSubpathFromConfig(s.Config())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to parse SiteURL subpath")
|
||||
@@ -1914,12 +1905,8 @@ func (s *Server) ClusterHealthScore() int {
|
||||
return s.Cluster.HealthScore()
|
||||
}
|
||||
|
||||
func (s *Server) configOrLicenseListener() {
|
||||
s.regenerateClientConfig()
|
||||
}
|
||||
|
||||
func (s *Server) ClientConfigHash() string {
|
||||
return s.clientConfigHash.Load().(string)
|
||||
func (ch *Channels) ClientConfigHash() string {
|
||||
return ch.clientConfigHash.Load().(string)
|
||||
}
|
||||
|
||||
func (s *Server) initJobs() {
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
package configservice
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
)
|
||||
|
||||
@@ -14,5 +12,4 @@ type ConfigService interface {
|
||||
Config() *model.Config
|
||||
AddConfigListener(func(old, current *model.Config)) string
|
||||
RemoveConfigListener(string)
|
||||
AsymmetricSigningKey() *ecdsa.PrivateKey
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user