github.com/spline-fu/mattermost-server@v4.10.10+incompatible/app/license.go (about) 1 // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package app 5 6 import ( 7 "crypto/md5" 8 "fmt" 9 "net/http" 10 "strings" 11 12 "github.com/mattermost/mattermost-server/mlog" 13 "github.com/mattermost/mattermost-server/model" 14 "github.com/mattermost/mattermost-server/utils" 15 ) 16 17 func (a *App) LoadLicense() { 18 a.SetLicense(nil) 19 20 licenseId := "" 21 if result := <-a.Srv.Store.System().Get(); result.Err == nil { 22 props := result.Data.(model.StringMap) 23 licenseId = props[model.SYSTEM_ACTIVE_LICENSE_ID] 24 } 25 26 if len(licenseId) != 26 { 27 // Lets attempt to load the file from disk since it was missing from the DB 28 license, licenseBytes := utils.GetAndValidateLicenseFileFromDisk(*a.Config().ServiceSettings.LicenseFileLocation) 29 30 if license != nil { 31 if _, err := a.SaveLicense(licenseBytes); err != nil { 32 mlog.Info(fmt.Sprintf("Failed to save license key loaded from disk err=%v", err.Error())) 33 } else { 34 licenseId = license.Id 35 } 36 } 37 } 38 39 if result := <-a.Srv.Store.License().Get(licenseId); result.Err == nil { 40 record := result.Data.(*model.LicenseRecord) 41 a.ValidateAndSetLicenseBytes([]byte(record.Bytes)) 42 mlog.Info("License key valid unlocking enterprise features.") 43 } else { 44 mlog.Info("License key from https://mattermost.com required to unlock enterprise features.") 45 } 46 } 47 48 func (a *App) SaveLicense(licenseBytes []byte) (*model.License, *model.AppError) { 49 var license *model.License 50 51 if success, licenseStr := utils.ValidateLicense(licenseBytes); success { 52 license = model.LicenseFromJson(strings.NewReader(licenseStr)) 53 54 if result := <-a.Srv.Store.User().AnalyticsUniqueUserCount(""); result.Err != nil { 55 return nil, model.NewAppError("addLicense", "api.license.add_license.invalid_count.app_error", nil, result.Err.Error(), http.StatusBadRequest) 56 } else { 57 uniqueUserCount := result.Data.(int64) 58 59 if uniqueUserCount > int64(*license.Features.Users) { 60 return nil, model.NewAppError("addLicense", "api.license.add_license.unique_users.app_error", map[string]interface{}{"Users": *license.Features.Users, "Count": uniqueUserCount}, "", http.StatusBadRequest) 61 } 62 } 63 64 if ok := a.SetLicense(license); !ok { 65 return nil, model.NewAppError("addLicense", model.EXPIRED_LICENSE_ERROR, nil, "", http.StatusBadRequest) 66 } 67 68 record := &model.LicenseRecord{} 69 record.Id = license.Id 70 record.Bytes = string(licenseBytes) 71 rchan := a.Srv.Store.License().Save(record) 72 73 if result := <-rchan; result.Err != nil { 74 a.RemoveLicense() 75 return nil, model.NewAppError("addLicense", "api.license.add_license.save.app_error", nil, "err="+result.Err.Error(), http.StatusInternalServerError) 76 } 77 78 sysVar := &model.System{} 79 sysVar.Name = model.SYSTEM_ACTIVE_LICENSE_ID 80 sysVar.Value = license.Id 81 schan := a.Srv.Store.System().SaveOrUpdate(sysVar) 82 83 if result := <-schan; result.Err != nil { 84 a.RemoveLicense() 85 return nil, model.NewAppError("addLicense", "api.license.add_license.save_active.app_error", nil, "", http.StatusInternalServerError) 86 } 87 } else { 88 return nil, model.NewAppError("addLicense", model.INVALID_LICENSE_ERROR, nil, "", http.StatusBadRequest) 89 } 90 91 a.ReloadConfig() 92 a.InvalidateAllCaches() 93 94 // start job server if necessary - this handles the edge case where a license file is uploaded, but the job server 95 // doesn't start until the server is restarted, which prevents the 'run job now' buttons in system console from 96 // functioning as expected 97 if *a.Config().JobSettings.RunJobs { 98 a.Jobs.StartWorkers() 99 } 100 if *a.Config().JobSettings.RunScheduler { 101 a.Jobs.StartSchedulers() 102 } 103 104 return license, nil 105 } 106 107 // License returns the currently active license or nil if the application is unlicensed. 108 func (a *App) License() *model.License { 109 license, _ := a.licenseValue.Load().(*model.License) 110 return license 111 } 112 113 func (a *App) SetLicense(license *model.License) bool { 114 defer func() { 115 for _, listener := range a.licenseListeners { 116 listener() 117 } 118 }() 119 120 if license != nil { 121 license.Features.SetDefaults() 122 123 if !license.IsExpired() { 124 a.licenseValue.Store(license) 125 a.clientLicenseValue.Store(utils.GetClientLicense(license)) 126 return true 127 } 128 } 129 130 a.licenseValue.Store((*model.License)(nil)) 131 a.clientLicenseValue.Store(map[string]string(nil)) 132 return false 133 } 134 135 func (a *App) ValidateAndSetLicenseBytes(b []byte) { 136 if success, licenseStr := utils.ValidateLicense(b); success { 137 license := model.LicenseFromJson(strings.NewReader(licenseStr)) 138 a.SetLicense(license) 139 return 140 } 141 142 mlog.Warn("No valid enterprise license found") 143 } 144 145 func (a *App) SetClientLicense(m map[string]string) { 146 a.clientLicenseValue.Store(m) 147 } 148 149 func (a *App) ClientLicense() map[string]string { 150 if clientLicense, _ := a.clientLicenseValue.Load().(map[string]string); clientLicense != nil { 151 return clientLicense 152 } 153 return map[string]string{"IsLicensed": "false"} 154 } 155 156 func (a *App) RemoveLicense() *model.AppError { 157 if license, _ := a.licenseValue.Load().(*model.License); license == nil { 158 return nil 159 } 160 161 sysVar := &model.System{} 162 sysVar.Name = model.SYSTEM_ACTIVE_LICENSE_ID 163 sysVar.Value = "" 164 165 if result := <-a.Srv.Store.System().SaveOrUpdate(sysVar); result.Err != nil { 166 return result.Err 167 } 168 169 a.SetLicense(nil) 170 a.ReloadConfig() 171 172 a.InvalidateAllCaches() 173 174 return nil 175 } 176 177 func (a *App) AddLicenseListener(listener func()) string { 178 id := model.NewId() 179 a.licenseListeners[id] = listener 180 return id 181 } 182 183 func (a *App) RemoveLicenseListener(id string) { 184 delete(a.licenseListeners, id) 185 } 186 187 func (a *App) GetClientLicenseEtag(useSanitized bool) string { 188 value := "" 189 190 lic := a.ClientLicense() 191 192 if useSanitized { 193 lic = a.GetSanitizedClientLicense() 194 } 195 196 for k, v := range lic { 197 value += fmt.Sprintf("%s:%s;", k, v) 198 } 199 200 return model.Etag(fmt.Sprintf("%x", md5.Sum([]byte(value)))) 201 } 202 203 func (a *App) GetSanitizedClientLicense() map[string]string { 204 sanitizedLicense := make(map[string]string) 205 206 for k, v := range a.ClientLicense() { 207 sanitizedLicense[k] = v 208 } 209 210 delete(sanitizedLicense, "Id") 211 delete(sanitizedLicense, "Name") 212 delete(sanitizedLicense, "Email") 213 delete(sanitizedLicense, "PhoneNumber") 214 delete(sanitizedLicense, "IssuedAt") 215 delete(sanitizedLicense, "StartsAt") 216 delete(sanitizedLicense, "ExpiresAt") 217 218 return sanitizedLicense 219 }