github.com/vnforks/kid@v5.11.1+incompatible/app/server_app_adapters.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package app 5 6 import ( 7 "fmt" 8 "net/http" 9 "net/url" 10 "path" 11 12 "github.com/mattermost/mattermost-server/mlog" 13 "github.com/mattermost/mattermost-server/model" 14 "github.com/mattermost/mattermost-server/services/mailservice" 15 "github.com/mattermost/mattermost-server/store" 16 "github.com/mattermost/mattermost-server/store/sqlstore" 17 "github.com/mattermost/mattermost-server/utils" 18 "github.com/pkg/errors" 19 ) 20 21 // This is a bridge between the old and new initalization for the context refactor. 22 // It calls app layer initalization code that then turns around and acts on the server. 23 // Don't add anything new here, new initilization should be done in the server and 24 // performed in the NewServer function. 25 func (s *Server) RunOldAppInitalization() error { 26 s.FakeApp().CreatePushNotificationsHub() 27 s.FakeApp().StartPushNotificationsHubWorkers() 28 29 if err := utils.InitTranslations(s.FakeApp().Config().LocalizationSettings); err != nil { 30 return errors.Wrapf(err, "unable to load Mattermost translation files") 31 } 32 33 s.FakeApp().Srv.configListenerId = s.FakeApp().AddConfigListener(func(_, _ *model.Config) { 34 s.FakeApp().configOrLicenseListener() 35 36 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CONFIG_CHANGED, "", "", "", nil) 37 38 message.Add("config", s.FakeApp().ClientConfigWithComputed()) 39 s.Go(func() { 40 s.FakeApp().Publish(message) 41 }) 42 }) 43 s.FakeApp().Srv.licenseListenerId = s.FakeApp().AddLicenseListener(func() { 44 s.FakeApp().configOrLicenseListener() 45 46 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_LICENSE_CHANGED, "", "", "", nil) 47 message.Add("license", s.FakeApp().GetSanitizedClientLicense()) 48 s.Go(func() { 49 s.FakeApp().Publish(message) 50 }) 51 52 }) 53 54 if err := s.FakeApp().SetupInviteEmailRateLimiting(); err != nil { 55 return err 56 } 57 58 mlog.Info("Server is initializing...") 59 60 s.initEnterprise() 61 62 if s.FakeApp().Srv.newStore == nil { 63 s.FakeApp().Srv.newStore = func() store.Store { 64 return store.NewLayeredStore(sqlstore.NewSqlSupplier(s.FakeApp().Config().SqlSettings, s.Metrics), s.Metrics, s.Cluster) 65 } 66 } 67 68 if htmlTemplateWatcher, err := utils.NewHTMLTemplateWatcher("templates"); err != nil { 69 mlog.Error(fmt.Sprintf("Failed to parse server templates %v", err)) 70 } else { 71 s.FakeApp().Srv.htmlTemplateWatcher = htmlTemplateWatcher 72 } 73 74 s.FakeApp().Srv.Store = s.FakeApp().Srv.newStore() 75 76 if err := s.FakeApp().ensureAsymmetricSigningKey(); err != nil { 77 return errors.Wrapf(err, "unable to ensure asymmetric signing key") 78 } 79 80 if err := s.FakeApp().ensurePostActionCookieSecret(); err != nil { 81 return errors.Wrapf(err, "unable to ensure PostAction cookie secret") 82 } 83 84 if err := s.FakeApp().ensureInstallationDate(); err != nil { 85 return errors.Wrapf(err, "unable to ensure installation date") 86 } 87 88 s.FakeApp().EnsureDiagnosticId() 89 s.FakeApp().regenerateClientConfig() 90 91 s.FakeApp().Srv.clusterLeaderListenerId = s.FakeApp().Srv.AddClusterLeaderChangedListener(func() { 92 mlog.Info("Cluster leader changed. Determining if job schedulers should be running:", mlog.Bool("isLeader", s.FakeApp().IsLeader())) 93 if s.FakeApp().Srv.Jobs != nil { 94 s.FakeApp().Srv.Jobs.Schedulers.HandleClusterLeaderChange(s.FakeApp().IsLeader()) 95 } 96 }) 97 98 subpath, err := utils.GetSubpathFromConfig(s.FakeApp().Config()) 99 if err != nil { 100 return errors.Wrap(err, "failed to parse SiteURL subpath") 101 } 102 s.FakeApp().Srv.Router = s.FakeApp().Srv.RootRouter.PathPrefix(subpath).Subrouter() 103 s.FakeApp().Srv.Router.HandleFunc("/plugins/{plugin_id:[A-Za-z0-9\\_\\-\\.]+}", s.FakeApp().ServePluginRequest) 104 s.FakeApp().Srv.Router.HandleFunc("/plugins/{plugin_id:[A-Za-z0-9\\_\\-\\.]+}/{anything:.*}", s.FakeApp().ServePluginRequest) 105 106 // If configured with a subpath, redirect 404s at the root back into the subpath. 107 if subpath != "/" { 108 s.FakeApp().Srv.RootRouter.NotFoundHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 109 r.URL.Path = path.Join(subpath, r.URL.Path) 110 http.Redirect(w, r, r.URL.String(), http.StatusFound) 111 }) 112 } 113 s.FakeApp().Srv.Router.NotFoundHandler = http.HandlerFunc(s.FakeApp().Handle404) 114 115 s.FakeApp().Srv.WebSocketRouter = &WebSocketRouter{ 116 app: s.FakeApp(), 117 handlers: make(map[string]webSocketHandler), 118 } 119 120 mailservice.TestConnection(s.FakeApp().Config()) 121 122 if _, err := url.ParseRequestURI(*s.FakeApp().Config().ServiceSettings.SiteURL); err != nil { 123 mlog.Error("SiteURL must be set. Some features will operate incorrectly if the SiteURL is not set. See documentation for details: http://about.mattermost.com/default-site-url") 124 } 125 126 backend, appErr := s.FakeApp().FileBackend() 127 if appErr == nil { 128 appErr = backend.TestConnection() 129 } 130 if appErr != nil { 131 mlog.Error("Problem with file storage settings: " + appErr.Error()) 132 } 133 134 if model.BuildEnterpriseReady == "true" { 135 s.FakeApp().LoadLicense() 136 } 137 138 s.FakeApp().DoAdvancedPermissionsMigration() 139 s.FakeApp().DoEmojisPermissionsMigration() 140 s.FakeApp().DoPermissionsMigrations() 141 142 s.FakeApp().InitPostMetadata() 143 144 s.FakeApp().InitPlugins(*s.Config().PluginSettings.Directory, *s.Config().PluginSettings.ClientDirectory) 145 s.FakeApp().AddConfigListener(func(prevCfg, cfg *model.Config) { 146 if *cfg.PluginSettings.Enable { 147 s.FakeApp().InitPlugins(*cfg.PluginSettings.Directory, *s.Config().PluginSettings.ClientDirectory) 148 } else { 149 s.FakeApp().ShutDownPlugins() 150 } 151 }) 152 153 return nil 154 } 155 156 func (s *Server) RunOldAppShutdown() { 157 s.FakeApp().HubStop() 158 s.FakeApp().StopPushNotificationsHubWorkers() 159 s.FakeApp().ShutDownPlugins() 160 s.FakeApp().RemoveLicenseListener(s.licenseListenerId) 161 s.RemoveClusterLeaderChangedListener(s.clusterLeaderListenerId) 162 } 163 164 // A temporary bridge to deal with cases where the code is so tighly coupled that 165 // this is easier as a temporary solution 166 func (s *Server) FakeApp() *App { 167 a := New( 168 ServerConnector(s), 169 ) 170 return a 171 }