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
```
Этот коммит содержится в:
Agniva De Sarker
2021-10-26 00:05:11 +05:30
коммит произвёл GitHub
родитель a499d2f378
Коммит 6bc6243131
4 изменённых файлов: 47 добавлений и 57 удалений

Просмотреть файл

@@ -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
}