"Fossies" - the Fresh Open Source Software Archive 
Member "mattermost-server-7.9.1/app/admin.go" (16 Mar 2023, 8300 Bytes) of package /linux/www/mattermost-server-7.9.1.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Go source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
See also the last
Fossies "Diffs" side-by-side code changes report for "admin.go":
7.8.1_vs_7.9.0.
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 "encoding/json"
8 "fmt"
9 "io"
10 "net/http"
11 "time"
12
13 "github.com/mattermost/mattermost-server/v6/model"
14 "github.com/mattermost/mattermost-server/v6/services/cache"
15 "github.com/mattermost/mattermost-server/v6/shared/i18n"
16 "github.com/mattermost/mattermost-server/v6/shared/mail"
17 "github.com/mattermost/mattermost-server/v6/shared/mlog"
18 )
19
20 var latestVersionCache = cache.NewLRU(cache.LRUOptions{
21 Size: 1,
22 })
23
24 func (s *Server) GetLogs(page, perPage int) ([]string, *model.AppError) {
25 var lines []string
26
27 license := s.License()
28 if license != nil && *license.Features.Cluster && s.platform.Cluster() != nil && *s.platform.Config().ClusterSettings.Enable {
29 if info := s.platform.Cluster().GetMyClusterInfo(); info != nil {
30 lines = append(lines, "-----------------------------------------------------------------------------------------------------------")
31 lines = append(lines, "-----------------------------------------------------------------------------------------------------------")
32 lines = append(lines, info.Hostname)
33 lines = append(lines, "-----------------------------------------------------------------------------------------------------------")
34 lines = append(lines, "-----------------------------------------------------------------------------------------------------------")
35 } else {
36 mlog.Error("Could not get cluster info")
37 }
38 }
39
40 melines, err := s.GetLogsSkipSend(page, perPage, &model.LogFilter{})
41 if err != nil {
42 return nil, err
43 }
44
45 lines = append(lines, melines...)
46
47 if s.platform.Cluster() != nil && *s.platform.Config().ClusterSettings.Enable {
48 clines, err := s.platform.Cluster().GetLogs(page, perPage)
49 if err != nil {
50 return nil, err
51 }
52
53 lines = append(lines, clines...)
54 }
55
56 return lines, nil
57 }
58
59 func (s *Server) QueryLogs(page, perPage int, logFilter *model.LogFilter) (map[string][]string, *model.AppError) {
60 logData := make(map[string][]string)
61
62 serverName := "default"
63
64 license := s.License()
65 if license != nil && *license.Features.Cluster && s.platform.Cluster() != nil && *s.platform.Config().ClusterSettings.Enable {
66 if info := s.platform.Cluster().GetMyClusterInfo(); info != nil {
67 serverName = info.Hostname
68 } else {
69 mlog.Error("Could not get cluster info")
70 }
71 }
72
73 serverNames := logFilter.ServerNames
74 if len(serverNames) > 0 {
75 for _, nodeName := range serverNames {
76 if nodeName == "default" {
77 AddLocalLogs(logData, s, page, perPage, nodeName, logFilter)
78 }
79 }
80 } else {
81 AddLocalLogs(logData, s, page, perPage, serverName, logFilter)
82 }
83
84 if s.platform.Cluster() != nil && *s.Config().ClusterSettings.Enable {
85 clusterLogs, err := s.platform.Cluster().QueryLogs(page, perPage)
86 if err != nil {
87 return nil, err
88 }
89
90 if clusterLogs != nil && len(serverNames) > 0 {
91 for _, filteredNodeName := range serverNames {
92 logData[filteredNodeName] = clusterLogs[filteredNodeName]
93 }
94 } else {
95 for nodeName, logs := range clusterLogs {
96 logData[nodeName] = logs
97 }
98 }
99 }
100
101 return logData, nil
102 }
103
104 func AddLocalLogs(logData map[string][]string, s *Server, page, perPage int, serverName string, logFilter *model.LogFilter) *model.AppError {
105 currentServerLogs, err := s.GetLogsSkipSend(page, perPage, logFilter)
106 if err != nil {
107 return err
108 }
109
110 logData[serverName] = currentServerLogs
111 return nil
112 }
113
114 func (a *App) QueryLogs(page, perPage int, logFilter *model.LogFilter) (map[string][]string, *model.AppError) {
115 return a.Srv().QueryLogs(page, perPage, logFilter)
116 }
117
118 func (a *App) GetLogs(page, perPage int) ([]string, *model.AppError) {
119 return a.Srv().GetLogs(page, perPage)
120 }
121
122 func (s *Server) GetLogsSkipSend(page, perPage int, logFilter *model.LogFilter) ([]string, *model.AppError) {
123 return s.platform.GetLogsSkipSend(page, perPage, logFilter)
124 }
125
126 func (a *App) GetLogsSkipSend(page, perPage int, logFilter *model.LogFilter) ([]string, *model.AppError) {
127 return a.Srv().GetLogsSkipSend(page, perPage, logFilter)
128 }
129
130 func (a *App) GetClusterStatus() []*model.ClusterInfo {
131 infos := make([]*model.ClusterInfo, 0)
132
133 if a.Cluster() != nil {
134 infos = a.Cluster().GetClusterInfos()
135 }
136
137 return infos
138 }
139
140 func (s *Server) InvalidateAllCaches() *model.AppError {
141 return s.platform.InvalidateAllCaches()
142 }
143
144 func (s *Server) InvalidateAllCachesSkipSend() {
145 s.platform.InvalidateAllCachesSkipSend()
146
147 }
148
149 func (a *App) RecycleDatabaseConnection() {
150 mlog.Info("Attempting to recycle database connections.")
151
152 // This works by setting 10 seconds as the max conn lifetime for all DB connections.
153 // This allows in gradually closing connections as they expire. In future, we can think
154 // of exposing this as a param from the REST api.
155 a.Srv().Store().RecycleDBConnections(10 * time.Second)
156
157 mlog.Info("Finished recycling database connections.")
158 }
159
160 func (a *App) TestSiteURL(siteURL string) *model.AppError {
161 url := fmt.Sprintf("%s/api/v4/system/ping", siteURL)
162 res, err := http.Get(url)
163 if err != nil || res.StatusCode != 200 {
164 return model.NewAppError("testSiteURL", "app.admin.test_site_url.failure", nil, "", http.StatusBadRequest)
165 }
166 defer func() {
167 _, _ = io.Copy(io.Discard, res.Body)
168 _ = res.Body.Close()
169 }()
170
171 return nil
172 }
173
174 func (a *App) TestEmail(userID string, cfg *model.Config) *model.AppError {
175 if *cfg.EmailSettings.SMTPServer == "" {
176 return model.NewAppError("testEmail", "api.admin.test_email.missing_server", nil, i18n.T("api.context.invalid_param.app_error", map[string]any{"Name": "SMTPServer"}), http.StatusBadRequest)
177 }
178
179 // if the user hasn't changed their email settings, fill in the actual SMTP password so that
180 // the user can verify an existing SMTP connection
181 if *cfg.EmailSettings.SMTPPassword == model.FakeSetting {
182 if *cfg.EmailSettings.SMTPServer == *a.Config().EmailSettings.SMTPServer &&
183 *cfg.EmailSettings.SMTPPort == *a.Config().EmailSettings.SMTPPort &&
184 *cfg.EmailSettings.SMTPUsername == *a.Config().EmailSettings.SMTPUsername {
185 *cfg.EmailSettings.SMTPPassword = *a.Config().EmailSettings.SMTPPassword
186 } else {
187 return model.NewAppError("testEmail", "api.admin.test_email.reenter_password", nil, "", http.StatusBadRequest)
188 }
189 }
190 user, err := a.GetUser(userID)
191 if err != nil {
192 return err
193 }
194
195 T := i18n.GetUserTranslations(user.Locale)
196 license := a.Srv().License()
197 mailConfig := a.Srv().MailServiceConfig()
198 if err := mail.SendMailUsingConfig(user.Email, T("api.admin.test_email.subject"), T("api.admin.test_email.body"), mailConfig, license != nil && *license.Features.Compliance, "", "", "", "", ""); err != nil {
199 return model.NewAppError("testEmail", "app.admin.test_email.failure", map[string]any{"Error": err.Error()}, "", http.StatusInternalServerError)
200 }
201
202 return nil
203 }
204
205 func (a *App) GetLatestVersion(latestVersionUrl string) (*model.GithubReleaseInfo, *model.AppError) {
206 var cachedLatestVersion *model.GithubReleaseInfo
207 if cacheErr := latestVersionCache.Get("latest_version_cache", &cachedLatestVersion); cacheErr == nil {
208 return cachedLatestVersion, nil
209 }
210
211 res, err := http.Get(latestVersionUrl)
212 if err != nil {
213 return nil, model.NewAppError("GetLatestVersion", model.NoTranslation, nil, "", http.StatusInternalServerError).Wrap(err)
214 }
215
216 defer res.Body.Close()
217
218 responseData, err := io.ReadAll(res.Body)
219 if err != nil {
220 return nil, model.NewAppError("GetLatestVersion", model.NoTranslation, nil, "", http.StatusInternalServerError).Wrap(err)
221 }
222
223 var releaseInfoResponse *model.GithubReleaseInfo
224 err = json.Unmarshal(responseData, &releaseInfoResponse)
225 if err != nil {
226 return nil, model.NewAppError("GetLatestVersion", model.NoTranslation, nil, "", http.StatusInternalServerError).Wrap(err)
227 }
228
229 if validErr := releaseInfoResponse.IsValid(); validErr != nil {
230 return nil, model.NewAppError("GetLatestVersion", model.NoTranslation, nil, "", http.StatusInternalServerError).Wrap(validErr)
231 }
232
233 err = latestVersionCache.Set("latest_version_cache", releaseInfoResponse)
234 if err != nil {
235 return nil, model.NewAppError("GetLatestVersion", model.NoTranslation, nil, "", http.StatusInternalServerError).Wrap(err)
236 }
237
238 return releaseInfoResponse, nil
239 }
240
241 func (a *App) ClearLatestVersionCache() {
242 latestVersionCache.Remove("latest_version_cache")
243 }