github.com/pafomin-at-avito/mattermost-server@v5.11.1+incompatible/app/security_update_check.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  	"io/ioutil"
     9  	"net/http"
    10  	"net/url"
    11  	"runtime"
    12  	"strconv"
    13  
    14  	"github.com/mattermost/mattermost-server/mlog"
    15  	"github.com/mattermost/mattermost-server/model"
    16  	"github.com/mattermost/mattermost-server/services/mailservice"
    17  	"github.com/mattermost/mattermost-server/utils"
    18  )
    19  
    20  const (
    21  	SECURITY_URL           = "https://securityupdatecheck.mattermost.com"
    22  	SECURITY_UPDATE_PERIOD = 86400000 // 24 hours in milliseconds.
    23  
    24  	PROP_SECURITY_ID                = "id"
    25  	PROP_SECURITY_BUILD             = "b"
    26  	PROP_SECURITY_ENTERPRISE_READY  = "be"
    27  	PROP_SECURITY_DATABASE          = "db"
    28  	PROP_SECURITY_OS                = "os"
    29  	PROP_SECURITY_USER_COUNT        = "uc"
    30  	PROP_SECURITY_TEAM_COUNT        = "tc"
    31  	PROP_SECURITY_ACTIVE_USER_COUNT = "auc"
    32  	PROP_SECURITY_UNIT_TESTS        = "ut"
    33  )
    34  
    35  func (s *Server) DoSecurityUpdateCheck() {
    36  	if *s.Config().ServiceSettings.EnableSecurityFixAlert {
    37  		if result := <-s.Store.System().Get(); result.Err == nil {
    38  			props := result.Data.(model.StringMap)
    39  			lastSecurityTime, _ := strconv.ParseInt(props[model.SYSTEM_LAST_SECURITY_TIME], 10, 0)
    40  			currentTime := model.GetMillis()
    41  
    42  			if (currentTime - lastSecurityTime) > SECURITY_UPDATE_PERIOD {
    43  				mlog.Debug("Checking for security update from Mattermost")
    44  
    45  				v := url.Values{}
    46  
    47  				v.Set(PROP_SECURITY_ID, s.diagnosticId)
    48  				v.Set(PROP_SECURITY_BUILD, model.CurrentVersion+"."+model.BuildNumber)
    49  				v.Set(PROP_SECURITY_ENTERPRISE_READY, model.BuildEnterpriseReady)
    50  				v.Set(PROP_SECURITY_DATABASE, *s.Config().SqlSettings.DriverName)
    51  				v.Set(PROP_SECURITY_OS, runtime.GOOS)
    52  
    53  				if len(props[model.SYSTEM_RAN_UNIT_TESTS]) > 0 {
    54  					v.Set(PROP_SECURITY_UNIT_TESTS, "1")
    55  				} else {
    56  					v.Set(PROP_SECURITY_UNIT_TESTS, "0")
    57  				}
    58  
    59  				systemSecurityLastTime := &model.System{Name: model.SYSTEM_LAST_SECURITY_TIME, Value: strconv.FormatInt(currentTime, 10)}
    60  				if lastSecurityTime == 0 {
    61  					<-s.Store.System().Save(systemSecurityLastTime)
    62  				} else {
    63  					<-s.Store.System().Update(systemSecurityLastTime)
    64  				}
    65  
    66  				if ucr := <-s.Store.User().Count(model.UserCountOptions{
    67  					IncludeDeleted: true,
    68  				}); ucr.Err == nil {
    69  					v.Set(PROP_SECURITY_USER_COUNT, strconv.FormatInt(ucr.Data.(int64), 10))
    70  				}
    71  
    72  				if ucr := <-s.Store.Status().GetTotalActiveUsersCount(); ucr.Err == nil {
    73  					v.Set(PROP_SECURITY_ACTIVE_USER_COUNT, strconv.FormatInt(ucr.Data.(int64), 10))
    74  				}
    75  
    76  				if tcr := <-s.Store.Team().AnalyticsTeamCount(); tcr.Err == nil {
    77  					v.Set(PROP_SECURITY_TEAM_COUNT, strconv.FormatInt(tcr.Data.(int64), 10))
    78  				}
    79  
    80  				res, err := http.Get(SECURITY_URL + "/security?" + v.Encode())
    81  				if err != nil {
    82  					mlog.Error("Failed to get security update information from Mattermost.")
    83  					return
    84  				}
    85  
    86  				defer res.Body.Close()
    87  
    88  				bulletins := model.SecurityBulletinsFromJson(res.Body)
    89  
    90  				for _, bulletin := range bulletins {
    91  					if bulletin.AppliesToVersion == model.CurrentVersion {
    92  						if props["SecurityBulletin_"+bulletin.Id] == "" {
    93  							results := <-s.Store.User().GetSystemAdminProfiles()
    94  							if results.Err != nil {
    95  								mlog.Error("Failed to get system admins for security update information from Mattermost.")
    96  								return
    97  							}
    98  							users := results.Data.(map[string]*model.User)
    99  
   100  							resBody, err := http.Get(SECURITY_URL + "/bulletins/" + bulletin.Id)
   101  							if err != nil {
   102  								mlog.Error("Failed to get security bulletin details")
   103  								return
   104  							}
   105  
   106  							body, err := ioutil.ReadAll(resBody.Body)
   107  							res.Body.Close()
   108  							if err != nil || resBody.StatusCode != 200 {
   109  								mlog.Error("Failed to read security bulletin details")
   110  								return
   111  							}
   112  
   113  							for _, user := range users {
   114  								mlog.Info(fmt.Sprintf("Sending security bulletin for %v to %v", bulletin.Id, user.Email))
   115  								license := s.License()
   116  								mailservice.SendMailUsingConfig(user.Email, utils.T("mattermost.bulletin.subject"), string(body), s.Config(), license != nil && *license.Features.Compliance)
   117  							}
   118  
   119  							bulletinSeen := &model.System{Name: "SecurityBulletin_" + bulletin.Id, Value: bulletin.Id}
   120  							<-s.Store.System().Save(bulletinSeen)
   121  						}
   122  					}
   123  				}
   124  			}
   125  		}
   126  	}
   127  }