From 591ef9f352efd98a85e6d04c0c9072c4c2987527 Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 5 Jan 2018 16:17:57 -0600 Subject: Remove utils.ClientCfg and utils.ClientCfgHash (#8041) * remove utils.ClientCfg and utils.ClientCfgHash * remove unused import --- api/context.go | 2 +- api/general.go | 3 +- api/user.go | 2 +- api4/context.go | 2 +- api4/system.go | 2 +- api4/team_test.go | 2 +- app/app.go | 61 +++++++++++++++++++++++++++++++++-- app/diagnostics.go | 76 ++++++++++++++++++++++---------------------- app/diagnostics_test.go | 14 +++----- app/email.go | 26 +++++++-------- app/notification.go | 2 +- app/security_update_check.go | 2 +- app/web_conn.go | 2 +- cmd/platform/server.go | 19 ++--------- utils/config.go | 14 ++------ utils/config_test.go | 2 +- utils/license.go | 19 +++++++++-- 17 files changed, 146 insertions(+), 104 deletions(-) diff --git a/api/context.go b/api/context.go index 2842e63a7..4f47271e2 100644 --- a/api/context.go +++ b/api/context.go @@ -151,7 +151,7 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { c.SetSiteURLHeader(app.GetProtocol(r) + "://" + r.Host) w.Header().Set(model.HEADER_REQUEST_ID, c.RequestId) - w.Header().Set(model.HEADER_VERSION_ID, fmt.Sprintf("%v.%v.%v.%v", model.CurrentVersion, model.BuildNumber, utils.ClientCfgHash, utils.IsLicensed())) + w.Header().Set(model.HEADER_VERSION_ID, fmt.Sprintf("%v.%v.%v.%v", model.CurrentVersion, model.BuildNumber, c.App.ClientConfigHash(), utils.IsLicensed())) // Instruct the browser not to display us in an iframe unless is the same origin for anti-clickjacking if !h.isApi { diff --git a/api/general.go b/api/general.go index 0fd289ffb..94da47330 100644 --- a/api/general.go +++ b/api/general.go @@ -9,7 +9,6 @@ import ( "strings" "github.com/mattermost/mattermost-server/model" - "github.com/mattermost/mattermost-server/utils" ) func (api *API) InitGeneral() { @@ -19,7 +18,7 @@ func (api *API) InitGeneral() { } func getClientConfig(c *Context, w http.ResponseWriter, r *http.Request) { - w.Write([]byte(model.MapToJson(utils.ClientCfg))) + w.Write([]byte(model.MapToJson(c.App.ClientConfig()))) } func logClient(c *Context, w http.ResponseWriter, r *http.Request) { diff --git a/api/user.go b/api/user.go index f9b0af469..55042498a 100644 --- a/api/user.go +++ b/api/user.go @@ -297,7 +297,7 @@ func getInitialLoad(c *Context, w http.ResponseWriter, r *http.Request) { il.NoAccounts = c.App.IsFirstUserAccount() } - il.ClientCfg = utils.ClientCfg + il.ClientCfg = c.App.ClientConfig() if c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) { il.LicenseCfg = utils.ClientLicense() } else { diff --git a/api4/context.go b/api4/context.go index 832b12414..6c46d1e4e 100644 --- a/api4/context.go +++ b/api4/context.go @@ -136,7 +136,7 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { c.SetSiteURLHeader(app.GetProtocol(r) + "://" + r.Host) w.Header().Set(model.HEADER_REQUEST_ID, c.RequestId) - w.Header().Set(model.HEADER_VERSION_ID, fmt.Sprintf("%v.%v.%v.%v", model.CurrentVersion, model.BuildNumber, utils.ClientCfgHash, utils.IsLicensed())) + w.Header().Set(model.HEADER_VERSION_ID, fmt.Sprintf("%v.%v.%v.%v", model.CurrentVersion, model.BuildNumber, c.App.ClientConfigHash(), utils.IsLicensed())) w.Header().Set("Content-Type", "application/json") diff --git a/api4/system.go b/api4/system.go index c87527ff0..43b941247 100644 --- a/api4/system.go +++ b/api4/system.go @@ -244,7 +244,7 @@ func getClientConfig(c *Context, w http.ResponseWriter, r *http.Request) { } respCfg := map[string]string{} - for k, v := range utils.ClientCfg { + for k, v := range c.App.ClientConfig() { respCfg[k] = v } diff --git a/api4/team_test.go b/api4/team_test.go index c26c34a22..b5c036755 100644 --- a/api4/team_test.go +++ b/api4/team_test.go @@ -1897,7 +1897,7 @@ func TestInviteUsersToTeam(t *testing.T) { expectedSubject := utils.T("api.templates.invite_subject", map[string]interface{}{"SenderName": th.SystemAdminUser.GetDisplayName(nameFormat), "TeamDisplayName": th.BasicTeam.DisplayName, - "SiteName": utils.ClientCfg["SiteName"]}) + "SiteName": th.App.ClientConfig()["SiteName"]}) //Check if the email was send to the rigth email address for _, email := range emailList { diff --git a/app/app.go b/app/app.go index 959c99306..4813926e2 100644 --- a/app/app.go +++ b/app/app.go @@ -4,6 +4,9 @@ package app import ( + "crypto/md5" + "encoding/json" + "fmt" "html/template" "net" "net/http" @@ -61,9 +64,14 @@ type App struct { sessionCache *utils.Cache roles map[string]*model.Role configListenerId string + licenseListenerId string pluginCommands []*PluginCommand pluginCommandsLock sync.RWMutex + + clientConfig map[string]string + clientConfigHash string + diagnosticId string } var appCount = 0 @@ -83,6 +91,7 @@ func New(options ...Option) *App { }, sessionCache: utils.NewLru(model.SESSION_CACHE_SIZE), configFile: "config.json", + clientConfig: make(map[string]string), } for _, option := range options { @@ -95,9 +104,11 @@ func New(options ...Option) *App { utils.LoadGlobalConfig(app.configFile) utils.InitTranslations(utils.Cfg.LocalizationSettings) - app.configListenerId = utils.AddConfigListener(func(_, cfg *model.Config) { - app.SetDefaultRolesBasedOnConfig() + app.configListenerId = utils.AddConfigListener(func(_, _ *model.Config) { + app.configOrLicenseListener() }) + app.licenseListenerId = utils.AddLicenseListener(app.configOrLicenseListener) + app.regenerateClientConfig() app.SetDefaultRolesBasedOnConfig() l4g.Info(utils.T("api.server.new_server.init.info")) @@ -133,6 +144,11 @@ func New(options ...Option) *App { return app } +func (a *App) configOrLicenseListener() { + a.regenerateClientConfig() + a.SetDefaultRolesBasedOnConfig() +} + func (a *App) Shutdown() { appCount-- @@ -152,6 +168,7 @@ func (a *App) Shutdown() { } utils.RemoveConfigListener(a.configListenerId) + utils.RemoveLicenseListener(a.licenseListenerId) l4g.Info(utils.T("api.server.stop_server.stopped.info")) } @@ -349,6 +366,46 @@ func (a *App) ConfigFileName() string { return utils.CfgFileName } +func (a *App) ClientConfig() map[string]string { + return a.clientConfig +} + +func (a *App) ClientConfigHash() string { + return a.clientConfigHash +} + +func (a *App) regenerateClientConfig() { + a.clientConfig = utils.GenerateClientConfig(a.Config(), a.DiagnosticId()) + clientConfigJSON, _ := json.Marshal(a.clientConfig) + a.clientConfigHash = fmt.Sprintf("%x", md5.Sum(clientConfigJSON)) +} + +func (a *App) DiagnosticId() string { + return a.diagnosticId +} + +func (a *App) SetDiagnosticId(id string) { + a.diagnosticId = id +} + +func (a *App) EnsureDiagnosticId() { + if a.diagnosticId != "" { + return + } + if result := <-a.Srv.Store.System().Get(); result.Err == nil { + props := result.Data.(model.StringMap) + + id := props[model.SYSTEM_DIAGNOSTIC_ID] + if len(id) == 0 { + id = model.NewId() + systemId := &model.System{Name: model.SYSTEM_DIAGNOSTIC_ID, Value: id} + <-a.Srv.Store.System().Save(systemId) + } + + a.diagnosticId = id + } +} + // Go creates a goroutine, but maintains a record of it to ensure that execution completes before // the app is destroyed. func (a *App) Go(f func()) { diff --git a/app/diagnostics.go b/app/diagnostics.go index e19be15c6..8fd7f9c85 100644 --- a/app/diagnostics.go +++ b/app/diagnostics.go @@ -56,16 +56,16 @@ var client *analytics.Client func (a *App) SendDailyDiagnostics() { if *a.Config().LogSettings.EnableDiagnostics && a.IsLeader() { - initDiagnostics("") + a.initDiagnostics("") a.trackActivity() a.trackConfig() - trackLicense() + a.trackLicense() a.trackPlugins() a.trackServer() } } -func initDiagnostics(endpoint string) { +func (a *App) initDiagnostics(endpoint string) { if client == nil { client = analytics.New(SEGMENT_KEY) // For testing @@ -76,15 +76,15 @@ func initDiagnostics(endpoint string) { client.Logger = log.New(os.Stdout, "segment ", log.LstdFlags) } client.Identify(&analytics.Identify{ - UserId: utils.CfgDiagnosticId, + UserId: a.DiagnosticId(), }) } } -func SendDiagnostic(event string, properties map[string]interface{}) { +func (a *App) SendDiagnostic(event string, properties map[string]interface{}) { client.Track(&analytics.Track{ Event: event, - UserId: utils.CfgDiagnosticId, + UserId: a.DiagnosticId(), Properties: properties, }) } @@ -170,7 +170,7 @@ func (a *App) trackActivity() { postsCount = pcr.Data.(int64) } - SendDiagnostic(TRACK_ACTIVITY, map[string]interface{}{ + a.SendDiagnostic(TRACK_ACTIVITY, map[string]interface{}{ "registered_users": userCount, "active_users": activeUserCount, "registered_inactive_users": inactiveUserCount, @@ -189,7 +189,7 @@ func (a *App) trackActivity() { func (a *App) trackConfig() { cfg := a.Config() - SendDiagnostic(TRACK_CONFIG_SERVICE, map[string]interface{}{ + a.SendDiagnostic(TRACK_CONFIG_SERVICE, map[string]interface{}{ "web_server_mode": *cfg.ServiceSettings.WebserverMode, "enable_security_fix_alert": *cfg.ServiceSettings.EnableSecurityFixAlert, "enable_insecure_outgoing_connections": *cfg.ServiceSettings.EnableInsecureOutgoingConnections, @@ -239,7 +239,7 @@ func (a *App) trackConfig() { "close_unused_direct_messages": *cfg.ServiceSettings.CloseUnusedDirectMessages, }) - SendDiagnostic(TRACK_CONFIG_TEAM, map[string]interface{}{ + a.SendDiagnostic(TRACK_CONFIG_TEAM, map[string]interface{}{ "enable_user_creation": cfg.TeamSettings.EnableUserCreation, "enable_team_creation": cfg.TeamSettings.EnableTeamCreation, "restrict_team_invite": *cfg.TeamSettings.RestrictTeamInvite, @@ -266,7 +266,7 @@ func (a *App) trackConfig() { "experimental_town_square_is_read_only": *cfg.TeamSettings.ExperimentalTownSquareIsReadOnly, }) - SendDiagnostic(TRACK_CONFIG_CLIENT_REQ, map[string]interface{}{ + a.SendDiagnostic(TRACK_CONFIG_CLIENT_REQ, map[string]interface{}{ "android_latest_version": cfg.ClientRequirements.AndroidLatestVersion, "android_min_version": cfg.ClientRequirements.AndroidMinVersion, "desktop_latest_version": cfg.ClientRequirements.DesktopLatestVersion, @@ -275,7 +275,7 @@ func (a *App) trackConfig() { "ios_min_version": cfg.ClientRequirements.IosMinVersion, }) - SendDiagnostic(TRACK_CONFIG_SQL, map[string]interface{}{ + a.SendDiagnostic(TRACK_CONFIG_SQL, map[string]interface{}{ "driver_name": *cfg.SqlSettings.DriverName, "trace": cfg.SqlSettings.Trace, "max_idle_conns": *cfg.SqlSettings.MaxIdleConns, @@ -285,7 +285,7 @@ func (a *App) trackConfig() { "query_timeout": *cfg.SqlSettings.QueryTimeout, }) - SendDiagnostic(TRACK_CONFIG_LOG, map[string]interface{}{ + a.SendDiagnostic(TRACK_CONFIG_LOG, map[string]interface{}{ "enable_console": cfg.LogSettings.EnableConsole, "console_level": cfg.LogSettings.ConsoleLevel, "enable_file": cfg.LogSettings.EnableFile, @@ -295,7 +295,7 @@ func (a *App) trackConfig() { "isdefault_file_location": isDefault(cfg.LogSettings.FileLocation, ""), }) - SendDiagnostic(TRACK_CONFIG_PASSWORD, map[string]interface{}{ + a.SendDiagnostic(TRACK_CONFIG_PASSWORD, map[string]interface{}{ "minimum_length": *cfg.PasswordSettings.MinimumLength, "lowercase": *cfg.PasswordSettings.Lowercase, "number": *cfg.PasswordSettings.Number, @@ -303,7 +303,7 @@ func (a *App) trackConfig() { "symbol": *cfg.PasswordSettings.Symbol, }) - SendDiagnostic(TRACK_CONFIG_FILE, map[string]interface{}{ + a.SendDiagnostic(TRACK_CONFIG_FILE, map[string]interface{}{ "enable_public_links": cfg.FileSettings.EnablePublicLink, "driver_name": *cfg.FileSettings.DriverName, "amazon_s3_ssl": *cfg.FileSettings.AmazonS3SSL, @@ -316,7 +316,7 @@ func (a *App) trackConfig() { "enable_mobile_download": *cfg.FileSettings.EnableMobileDownload, }) - SendDiagnostic(TRACK_CONFIG_EMAIL, map[string]interface{}{ + a.SendDiagnostic(TRACK_CONFIG_EMAIL, map[string]interface{}{ "enable_sign_up_with_email": cfg.EmailSettings.EnableSignUpWithEmail, "enable_sign_in_with_email": *cfg.EmailSettings.EnableSignInWithEmail, "enable_sign_in_with_username": *cfg.EmailSettings.EnableSignInWithUsername, @@ -336,7 +336,7 @@ func (a *App) trackConfig() { "skip_server_certificate_verification": *cfg.EmailSettings.SkipServerCertificateVerification, }) - SendDiagnostic(TRACK_CONFIG_RATE, map[string]interface{}{ + a.SendDiagnostic(TRACK_CONFIG_RATE, map[string]interface{}{ "enable_rate_limiter": *cfg.RateLimitSettings.Enable, "vary_by_remote_address": cfg.RateLimitSettings.VaryByRemoteAddr, "per_sec": *cfg.RateLimitSettings.PerSec, @@ -345,25 +345,25 @@ func (a *App) trackConfig() { "isdefault_vary_by_header": isDefault(cfg.RateLimitSettings.VaryByHeader, ""), }) - SendDiagnostic(TRACK_CONFIG_PRIVACY, map[string]interface{}{ + a.SendDiagnostic(TRACK_CONFIG_PRIVACY, map[string]interface{}{ "show_email_address": cfg.PrivacySettings.ShowEmailAddress, "show_full_name": cfg.PrivacySettings.ShowFullName, }) - SendDiagnostic(TRACK_CONFIG_THEME, map[string]interface{}{ + a.SendDiagnostic(TRACK_CONFIG_THEME, map[string]interface{}{ "enable_theme_selection": *cfg.ThemeSettings.EnableThemeSelection, "isdefault_default_theme": isDefault(*cfg.ThemeSettings.DefaultTheme, model.TEAM_SETTINGS_DEFAULT_TEAM_TEXT), "allow_custom_themes": *cfg.ThemeSettings.AllowCustomThemes, "allowed_themes": len(cfg.ThemeSettings.AllowedThemes), }) - SendDiagnostic(TRACK_CONFIG_OAUTH, map[string]interface{}{ + a.SendDiagnostic(TRACK_CONFIG_OAUTH, map[string]interface{}{ "enable_gitlab": cfg.GitLabSettings.Enable, "enable_google": cfg.GoogleSettings.Enable, "enable_office365": cfg.Office365Settings.Enable, }) - SendDiagnostic(TRACK_CONFIG_SUPPORT, map[string]interface{}{ + a.SendDiagnostic(TRACK_CONFIG_SUPPORT, map[string]interface{}{ "isdefault_terms_of_service_link": isDefault(*cfg.SupportSettings.TermsOfServiceLink, model.SUPPORT_SETTINGS_DEFAULT_TERMS_OF_SERVICE_LINK), "isdefault_privacy_policy_link": isDefault(*cfg.SupportSettings.PrivacyPolicyLink, model.SUPPORT_SETTINGS_DEFAULT_PRIVACY_POLICY_LINK), "isdefault_about_link": isDefault(*cfg.SupportSettings.AboutLink, model.SUPPORT_SETTINGS_DEFAULT_ABOUT_LINK), @@ -372,7 +372,7 @@ func (a *App) trackConfig() { "isdefault_support_email": isDefault(*cfg.SupportSettings.SupportEmail, model.SUPPORT_SETTINGS_DEFAULT_SUPPORT_EMAIL), }) - SendDiagnostic(TRACK_CONFIG_LDAP, map[string]interface{}{ + a.SendDiagnostic(TRACK_CONFIG_LDAP, map[string]interface{}{ "enable": *cfg.LdapSettings.Enable, "enable_sync": *cfg.LdapSettings.EnableSync, "connection_security": *cfg.LdapSettings.ConnectionSecurity, @@ -390,18 +390,18 @@ func (a *App) trackConfig() { "isdefault_login_field_name": isDefault(*cfg.LdapSettings.LoginFieldName, model.LDAP_SETTINGS_DEFAULT_LOGIN_FIELD_NAME), }) - SendDiagnostic(TRACK_CONFIG_COMPLIANCE, map[string]interface{}{ + a.SendDiagnostic(TRACK_CONFIG_COMPLIANCE, map[string]interface{}{ "enable": *cfg.ComplianceSettings.Enable, "enable_daily": *cfg.ComplianceSettings.EnableDaily, }) - SendDiagnostic(TRACK_CONFIG_LOCALIZATION, map[string]interface{}{ + a.SendDiagnostic(TRACK_CONFIG_LOCALIZATION, map[string]interface{}{ "default_server_locale": *cfg.LocalizationSettings.DefaultServerLocale, "default_client_locale": *cfg.LocalizationSettings.DefaultClientLocale, "available_locales": *cfg.LocalizationSettings.AvailableLocales, }) - SendDiagnostic(TRACK_CONFIG_SAML, map[string]interface{}{ + a.SendDiagnostic(TRACK_CONFIG_SAML, map[string]interface{}{ "enable": *cfg.SamlSettings.Enable, "enable_sync_with_ldap": *cfg.SamlSettings.EnableSyncWithLdap, "verify": *cfg.SamlSettings.Verify, @@ -416,42 +416,42 @@ func (a *App) trackConfig() { "isdefault_login_button_text": isDefault(*cfg.SamlSettings.LoginButtonText, model.USER_AUTH_SERVICE_SAML_TEXT), }) - SendDiagnostic(TRACK_CONFIG_CLUSTER, map[string]interface{}{ + a.SendDiagnostic(TRACK_CONFIG_CLUSTER, map[string]interface{}{ "enable": *cfg.ClusterSettings.Enable, "use_ip_address": *cfg.ClusterSettings.UseIpAddress, "use_experimental_gossip": *cfg.ClusterSettings.UseExperimentalGossip, "read_only_config": *cfg.ClusterSettings.ReadOnlyConfig, }) - SendDiagnostic(TRACK_CONFIG_METRICS, map[string]interface{}{ + a.SendDiagnostic(TRACK_CONFIG_METRICS, map[string]interface{}{ "enable": *cfg.MetricsSettings.Enable, "block_profile_rate": *cfg.MetricsSettings.BlockProfileRate, }) - SendDiagnostic(TRACK_CONFIG_NATIVEAPP, map[string]interface{}{ + a.SendDiagnostic(TRACK_CONFIG_NATIVEAPP, map[string]interface{}{ "isdefault_app_download_link": isDefault(*cfg.NativeAppSettings.AppDownloadLink, model.NATIVEAPP_SETTINGS_DEFAULT_APP_DOWNLOAD_LINK), "isdefault_android_app_download_link": isDefault(*cfg.NativeAppSettings.AndroidAppDownloadLink, model.NATIVEAPP_SETTINGS_DEFAULT_ANDROID_APP_DOWNLOAD_LINK), "isdefault_iosapp_download_link": isDefault(*cfg.NativeAppSettings.IosAppDownloadLink, model.NATIVEAPP_SETTINGS_DEFAULT_IOS_APP_DOWNLOAD_LINK), }) - SendDiagnostic(TRACK_CONFIG_WEBRTC, map[string]interface{}{ + a.SendDiagnostic(TRACK_CONFIG_WEBRTC, map[string]interface{}{ "enable": *cfg.WebrtcSettings.Enable, "isdefault_stun_uri": isDefault(*cfg.WebrtcSettings.StunURI, model.WEBRTC_SETTINGS_DEFAULT_STUN_URI), "isdefault_turn_uri": isDefault(*cfg.WebrtcSettings.TurnURI, model.WEBRTC_SETTINGS_DEFAULT_TURN_URI), }) - SendDiagnostic(TRACK_CONFIG_ANALYTICS, map[string]interface{}{ + a.SendDiagnostic(TRACK_CONFIG_ANALYTICS, map[string]interface{}{ "isdefault_max_users_for_statistics": isDefault(*cfg.AnalyticsSettings.MaxUsersForStatistics, model.ANALYTICS_SETTINGS_DEFAULT_MAX_USERS_FOR_STATISTICS), }) - SendDiagnostic(TRACK_CONFIG_ANNOUNCEMENT, map[string]interface{}{ + a.SendDiagnostic(TRACK_CONFIG_ANNOUNCEMENT, map[string]interface{}{ "enable_banner": *cfg.AnnouncementSettings.EnableBanner, "isdefault_banner_color": isDefault(*cfg.AnnouncementSettings.BannerColor, model.ANNOUNCEMENT_SETTINGS_DEFAULT_BANNER_COLOR), "isdefault_banner_text_color": isDefault(*cfg.AnnouncementSettings.BannerTextColor, model.ANNOUNCEMENT_SETTINGS_DEFAULT_BANNER_TEXT_COLOR), "allow_banner_dismissal": *cfg.AnnouncementSettings.AllowBannerDismissal, }) - SendDiagnostic(TRACK_CONFIG_ELASTICSEARCH, map[string]interface{}{ + a.SendDiagnostic(TRACK_CONFIG_ELASTICSEARCH, map[string]interface{}{ "isdefault_connection_url": isDefault(*cfg.ElasticsearchSettings.ConnectionUrl, model.ELASTICSEARCH_SETTINGS_DEFAULT_CONNECTION_URL), "isdefault_username": isDefault(*cfg.ElasticsearchSettings.Username, model.ELASTICSEARCH_SETTINGS_DEFAULT_USERNAME), "isdefault_password": isDefault(*cfg.ElasticsearchSettings.Password, model.ELASTICSEARCH_SETTINGS_DEFAULT_PASSWORD), @@ -466,14 +466,14 @@ func (a *App) trackConfig() { "request_timeout_seconds": *cfg.ElasticsearchSettings.RequestTimeoutSeconds, }) - SendDiagnostic(TRACK_CONFIG_PLUGIN, map[string]interface{}{ + a.SendDiagnostic(TRACK_CONFIG_PLUGIN, map[string]interface{}{ "enable_jira": pluginSetting(&cfg.PluginSettings, "jira", "enabled", false), "enable_zoom": pluginActivated(cfg.PluginSettings.PluginStates, "zoom"), "enable": *cfg.PluginSettings.Enable, "enable_uploads": *cfg.PluginSettings.EnableUploads, }) - SendDiagnostic(TRACK_CONFIG_DATA_RETENTION, map[string]interface{}{ + a.SendDiagnostic(TRACK_CONFIG_DATA_RETENTION, map[string]interface{}{ "enable_message_deletion": *cfg.DataRetentionSettings.EnableMessageDeletion, "enable_file_deletion": *cfg.DataRetentionSettings.EnableFileDeletion, "message_retention_days": *cfg.DataRetentionSettings.MessageRetentionDays, @@ -481,7 +481,7 @@ func (a *App) trackConfig() { "deletion_job_start_time": *cfg.DataRetentionSettings.DeletionJobStartTime, }) - SendDiagnostic(TRACK_CONFIG_MESSAGE_EXPORT, map[string]interface{}{ + a.SendDiagnostic(TRACK_CONFIG_MESSAGE_EXPORT, map[string]interface{}{ "enable_message_export": *cfg.MessageExportSettings.EnableExport, "daily_run_time": *cfg.MessageExportSettings.DailyRunTime, "default_export_from_timestamp": *cfg.MessageExportSettings.ExportFromTimestamp, @@ -489,7 +489,7 @@ func (a *App) trackConfig() { }) } -func trackLicense() { +func (a *App) trackLicense() { if utils.IsLicensed() { data := map[string]interface{}{ "customer_id": utils.License().Customer.Id, @@ -505,7 +505,7 @@ func trackLicense() { data["feature_"+featureName] = featureValue } - SendDiagnostic(TRACK_LICENSE, data) + a.SendDiagnostic(TRACK_LICENSE, data) } } @@ -555,7 +555,7 @@ func (a *App) trackPlugins() { } } - SendDiagnostic(TRACK_PLUGINS, map[string]interface{}{ + a.SendDiagnostic(TRACK_PLUGINS, map[string]interface{}{ "active_plugins": totalActiveCount, "active_webapp_plugins": webappActiveCount, "active_backend_plugins": backendActiveCount, @@ -579,5 +579,5 @@ func (a *App) trackServer() { data["system_admins"] = scr.Data.(int64) } - SendDiagnostic(TRACK_SERVER, data) + a.SendDiagnostic(TRACK_SERVER, data) } diff --git a/app/diagnostics_test.go b/app/diagnostics_test.go index 0d1c7acd8..0869e4df4 100644 --- a/app/diagnostics_test.go +++ b/app/diagnostics_test.go @@ -15,7 +15,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/mattermost/mattermost-server/model" - "github.com/mattermost/mattermost-server/utils" ) func newTestServer() (chan string, *httptest.Server) { @@ -68,18 +67,15 @@ func TestDiagnostics(t *testing.T) { data, server := newTestServer() defer server.Close() - oldId := utils.CfgDiagnosticId - utils.CfgDiagnosticId = "i am not real" - defer func() { - utils.CfgDiagnosticId = oldId - }() - initDiagnostics(server.URL) + diagnosticId := "i am not real" + th.App.SetDiagnosticId(diagnosticId) + th.App.initDiagnostics(server.URL) // Should send a client identify message select { case identifyMessage := <-data: t.Log("Got idmessage:\n" + identifyMessage) - if !strings.Contains(identifyMessage, utils.CfgDiagnosticId) { + if !strings.Contains(identifyMessage, diagnosticId) { t.Fail() } case <-time.After(time.Second * 1): @@ -88,7 +84,7 @@ func TestDiagnostics(t *testing.T) { t.Run("Send", func(t *testing.T) { const TEST_VALUE = "stuff548959847" - SendDiagnostic("Testing Diagnostic", map[string]interface{}{ + th.App.SendDiagnostic("Testing Diagnostic", map[string]interface{}{ "hey": TEST_VALUE, }) select { diff --git a/app/email.go b/app/email.go index 867411960..b809b972d 100644 --- a/app/email.go +++ b/app/email.go @@ -20,7 +20,7 @@ func (a *App) SendChangeUsernameEmail(oldUsername, newUsername, email, locale, s T := utils.GetUserTranslations(locale) subject := T("api.templates.username_change_subject", - map[string]interface{}{"SiteName": utils.ClientCfg["SiteName"], + map[string]interface{}{"SiteName": a.ClientConfig()["SiteName"], "TeamDisplayName": a.Config().TeamSettings.SiteName}) bodyPage := a.NewEmailTemplate("email_change_body", locale) @@ -42,7 +42,7 @@ func (a *App) SendEmailChangeVerifyEmail(newUserEmail, locale, siteURL, token st link := fmt.Sprintf("%s/do_verify_email?token=%s&email=%s", siteURL, token, url.QueryEscape(newUserEmail)) subject := T("api.templates.email_change_verify_subject", - map[string]interface{}{"SiteName": utils.ClientCfg["SiteName"], + map[string]interface{}{"SiteName": a.ClientConfig()["SiteName"], "TeamDisplayName": a.Config().TeamSettings.SiteName}) bodyPage := a.NewEmailTemplate("email_change_verify_body", locale) @@ -64,7 +64,7 @@ func (a *App) SendEmailChangeEmail(oldEmail, newEmail, locale, siteURL string) * T := utils.GetUserTranslations(locale) subject := T("api.templates.email_change_subject", - map[string]interface{}{"SiteName": utils.ClientCfg["SiteName"], + map[string]interface{}{"SiteName": a.ClientConfig()["SiteName"], "TeamDisplayName": a.Config().TeamSettings.SiteName}) bodyPage := a.NewEmailTemplate("email_change_body", locale) @@ -88,7 +88,7 @@ func (a *App) SendVerifyEmail(userEmail, locale, siteURL, token string) *model.A url, _ := url.Parse(siteURL) subject := T("api.templates.verify_subject", - map[string]interface{}{"SiteName": utils.ClientCfg["SiteName"]}) + map[string]interface{}{"SiteName": a.ClientConfig()["SiteName"]}) bodyPage := a.NewEmailTemplate("verify_body", locale) bodyPage.Props["SiteURL"] = siteURL @@ -108,13 +108,13 @@ func (a *App) SendSignInChangeEmail(email, method, locale, siteURL string) *mode T := utils.GetUserTranslations(locale) subject := T("api.templates.signin_change_email.subject", - map[string]interface{}{"SiteName": utils.ClientCfg["SiteName"]}) + map[string]interface{}{"SiteName": a.ClientConfig()["SiteName"]}) bodyPage := a.NewEmailTemplate("signin_change_body", locale) bodyPage.Props["SiteURL"] = siteURL bodyPage.Props["Title"] = T("api.templates.signin_change_email.body.title") bodyPage.Html["Info"] = utils.TranslateAsHtml(T, "api.templates.signin_change_email.body.info", - map[string]interface{}{"SiteName": utils.ClientCfg["SiteName"], "Method": method}) + map[string]interface{}{"SiteName": a.ClientConfig()["SiteName"], "Method": method}) if err := a.SendMail(email, subject, bodyPage.Render()); err != nil { return model.NewAppError("SendSignInChangeEmail", "api.user.send_sign_in_change_email_and_forget.error", nil, err.Error(), http.StatusInternalServerError) @@ -129,7 +129,7 @@ func (a *App) SendWelcomeEmail(userId string, email string, verified bool, local rawUrl, _ := url.Parse(siteURL) subject := T("api.templates.welcome_subject", - map[string]interface{}{"SiteName": utils.ClientCfg["SiteName"], + map[string]interface{}{"SiteName": a.ClientConfig()["SiteName"], "ServerURL": rawUrl.Host}) bodyPage := a.NewEmailTemplate("welcome_body", locale) @@ -166,7 +166,7 @@ func (a *App) SendPasswordChangeEmail(email, method, locale, siteURL string) *mo T := utils.GetUserTranslations(locale) subject := T("api.templates.password_change_subject", - map[string]interface{}{"SiteName": utils.ClientCfg["SiteName"], + map[string]interface{}{"SiteName": a.ClientConfig()["SiteName"], "TeamDisplayName": a.Config().TeamSettings.SiteName}) bodyPage := a.NewEmailTemplate("password_change_body", locale) @@ -186,12 +186,12 @@ func (a *App) SendUserAccessTokenAddedEmail(email, locale string) *model.AppErro T := utils.GetUserTranslations(locale) subject := T("api.templates.user_access_token_subject", - map[string]interface{}{"SiteName": utils.ClientCfg["SiteName"]}) + map[string]interface{}{"SiteName": a.ClientConfig()["SiteName"]}) bodyPage := a.NewEmailTemplate("password_change_body", locale) bodyPage.Props["Title"] = T("api.templates.user_access_token_body.title") bodyPage.Html["Info"] = utils.TranslateAsHtml(T, "api.templates.user_access_token_body.info", - map[string]interface{}{"SiteName": utils.ClientCfg["SiteName"], "SiteURL": utils.GetSiteURL()}) + map[string]interface{}{"SiteName": a.ClientConfig()["SiteName"], "SiteURL": utils.GetSiteURL()}) if err := a.SendMail(email, subject, bodyPage.Render()); err != nil { return model.NewAppError("SendUserAccessTokenAddedEmail", "api.user.send_user_access_token.error", nil, err.Error(), http.StatusInternalServerError) @@ -207,7 +207,7 @@ func (a *App) SendPasswordResetEmail(email string, token *model.Token, locale, s link := fmt.Sprintf("%s/reset_password_complete?token=%s", siteURL, url.QueryEscape(token.Token)) subject := T("api.templates.reset_subject", - map[string]interface{}{"SiteName": utils.ClientCfg["SiteName"]}) + map[string]interface{}{"SiteName": a.ClientConfig()["SiteName"]}) bodyPage := a.NewEmailTemplate("reset_body", locale) bodyPage.Props["SiteURL"] = siteURL @@ -227,7 +227,7 @@ func (a *App) SendMfaChangeEmail(email string, activated bool, locale, siteURL s T := utils.GetUserTranslations(locale) subject := T("api.templates.mfa_change_subject", - map[string]interface{}{"SiteName": utils.ClientCfg["SiteName"]}) + map[string]interface{}{"SiteName": a.ClientConfig()["SiteName"]}) bodyPage := a.NewEmailTemplate("mfa_change_body", locale) bodyPage.Props["SiteURL"] = siteURL @@ -258,7 +258,7 @@ func (a *App) SendInviteEmails(team *model.Team, senderName string, invites []st subject := utils.T("api.templates.invite_subject", map[string]interface{}{"SenderName": senderName, "TeamDisplayName": team.DisplayName, - "SiteName": utils.ClientCfg["SiteName"]}) + "SiteName": a.ClientConfig()["SiteName"]}) bodyPage := a.NewEmailTemplate("invite_body", model.DEFAULT_LOCALE) bodyPage.Props["SiteURL"] = siteURL diff --git a/app/notification.go b/app/notification.go index a7093e17f..4929d56f4 100644 --- a/app/notification.go +++ b/app/notification.go @@ -693,7 +693,7 @@ func (a *App) ClearPushNotification(userId string, channelId string) { } func (a *App) sendToPushProxy(msg model.PushNotification, session *model.Session) { - msg.ServerId = utils.CfgDiagnosticId + msg.ServerId = a.DiagnosticId() request, _ := http.NewRequest("POST", *a.Config().EmailSettings.PushNotificationServer+model.API_URL_SUFFIX_V1+"/send_push", strings.NewReader(msg.ToJson())) diff --git a/app/security_update_check.go b/app/security_update_check.go index dc26e59b2..1f1759fef 100644 --- a/app/security_update_check.go +++ b/app/security_update_check.go @@ -42,7 +42,7 @@ func (a *App) DoSecurityUpdateCheck() { v := url.Values{} - v.Set(PROP_SECURITY_ID, utils.CfgDiagnosticId) + v.Set(PROP_SECURITY_ID, a.DiagnosticId()) v.Set(PROP_SECURITY_BUILD, model.CurrentVersion+"."+model.BuildNumber) v.Set(PROP_SECURITY_ENTERPRISE_READY, model.BuildEnterpriseReady) v.Set(PROP_SECURITY_DATABASE, *a.Config().SqlSettings.DriverName) diff --git a/app/web_conn.go b/app/web_conn.go index 1c74e65a5..e625e61b5 100644 --- a/app/web_conn.go +++ b/app/web_conn.go @@ -277,7 +277,7 @@ func (webCon *WebConn) IsAuthenticated() bool { func (webCon *WebConn) SendHello() { msg := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_HELLO, "", "", webCon.UserId, nil) - msg.Add("server_version", fmt.Sprintf("%v.%v.%v.%v", model.CurrentVersion, model.BuildNumber, utils.ClientCfgHash, utils.IsLicensed())) + msg.Add("server_version", fmt.Sprintf("%v.%v.%v.%v", model.CurrentVersion, model.BuildNumber, webCon.App.ClientConfigHash(), utils.IsLicensed())) webCon.Send <- msg } diff --git a/cmd/platform/server.go b/cmd/platform/server.go index 4c36f5a46..d2abbffb9 100644 --- a/cmd/platform/server.go +++ b/cmd/platform/server.go @@ -117,8 +117,8 @@ func runServer(configFileLocation string) { manualtesting.Init(api3) } - setDiagnosticId(a) - utils.RegenerateClientConfig() + a.EnsureDiagnosticId() + go runSecurityJob(a) go runDiagnosticsJob(a) @@ -205,21 +205,6 @@ func resetStatuses(a *app.App) { } } -func setDiagnosticId(a *app.App) { - if result := <-a.Srv.Store.System().Get(); result.Err == nil { - props := result.Data.(model.StringMap) - - id := props[model.SYSTEM_DIAGNOSTIC_ID] - if len(id) == 0 { - id = model.NewId() - systemId := &model.System{Name: model.SYSTEM_DIAGNOSTIC_ID, Value: id} - <-a.Srv.Store.System().Save(systemId) - } - - utils.CfgDiagnosticId = id - } -} - func doSecurity(a *app.App) { a.DoSecurityUpdateCheck() } diff --git a/utils/config.go b/utils/config.go index e2622cff9..d75ec732b 100644 --- a/utils/config.go +++ b/utils/config.go @@ -37,12 +37,9 @@ const ( var cfgMutex = &sync.Mutex{} var watcher *fsnotify.Watcher var Cfg *model.Config = &model.Config{} -var CfgDiagnosticId = "" var CfgHash = "" -var ClientCfgHash = "" var CfgFileName string = "" var CfgDisableConfigWatch = false -var ClientCfg map[string]string = map[string]string{} var originalDisableDebugLvl l4g.Level = l4g.DEBUG var siteURL = "" @@ -416,9 +413,6 @@ func LoadGlobalConfig(fileName string) *model.Config { Cfg = config CfgHash = fmt.Sprintf("%x", md5.Sum([]byte(Cfg.ToJson()))) - ClientCfg = getClientConfig(Cfg) - clientCfgJson, _ := json.Marshal(ClientCfg) - ClientCfgHash = fmt.Sprintf("%x", md5.Sum(clientCfgJson)) SetSiteURL(*Cfg.ServiceSettings.SiteURL) @@ -433,11 +427,7 @@ func InvokeGlobalConfigListeners(old, current *model.Config) { } } -func RegenerateClientConfig() { - ClientCfg = getClientConfig(Cfg) -} - -func getClientConfig(c *model.Config) map[string]string { +func GenerateClientConfig(c *model.Config, diagnosticId string) map[string]string { props := make(map[string]string) props["Version"] = model.CurrentVersion @@ -544,7 +534,7 @@ func getClientConfig(c *model.Config) map[string]string { props["EnableUserTypingMessages"] = strconv.FormatBool(*c.ServiceSettings.EnableUserTypingMessages) props["EnableChannelViewedMessages"] = strconv.FormatBool(*c.ServiceSettings.EnableChannelViewedMessages) - props["DiagnosticId"] = CfgDiagnosticId + props["DiagnosticId"] = diagnosticId props["DiagnosticsEnabled"] = strconv.FormatBool(*c.LogSettings.EnableDiagnostics) props["PluginsEnabled"] = strconv.FormatBool(*c.PluginSettings.Enable) diff --git a/utils/config_test.go b/utils/config_test.go index 157fd7fed..8a89940e8 100644 --- a/utils/config_test.go +++ b/utils/config_test.go @@ -299,7 +299,7 @@ func TestGetClientConfig(t *testing.T) { TranslationsPreInit() LoadGlobalConfig("config.json") - configMap := getClientConfig(Cfg) + configMap := GenerateClientConfig(Cfg, "") if configMap["EmailNotificationContentsType"] != *Cfg.EmailSettings.EmailNotificationContentsType { t.Fatal("EmailSettings.EmailNotificationContentsType not exposed to client config") } diff --git a/utils/license.go b/utils/license.go index 54bad45b5..fa731c6b5 100644 --- a/utils/license.go +++ b/utils/license.go @@ -75,7 +75,24 @@ func LoadLicense(licenseBytes []byte) { l4g.Warn(T("utils.license.load_license.invalid.warn")) } +var licenseListeners = map[string]func(){} + +func AddLicenseListener(listener func()) string { + id := model.NewId() + licenseListeners[id] = listener + return id +} + +func RemoveLicenseListener(id string) { + delete(licenseListeners, id) +} + func SetLicense(license *model.License) bool { + defer func() { + for _, listener := range licenseListeners { + listener() + } + }() if license == nil { SetIsLicensed(false) @@ -95,7 +112,6 @@ func SetLicense(license *model.License) bool { licenseValue.Store(license) SetIsLicensed(true) clientLicenseValue.Store(getClientLicense(license)) - ClientCfg = getClientConfig(Cfg) return true } @@ -105,7 +121,6 @@ func SetLicense(license *model.License) bool { func RemoveLicense() { SetLicense(nil) - ClientCfg = getClientConfig(Cfg) } func ValidateLicense(signed []byte) (bool, string) { -- cgit v1.2.3-1-g7c22