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