diff options
author | Corey Hulen <corey@hulen.com> | 2017-03-31 06:54:30 -0700 |
---|---|---|
committer | Christopher Speller <crspeller@gmail.com> | 2017-03-31 09:54:30 -0400 |
commit | 00bb4799899cbbcdf48b147639dee3cee7ea199b (patch) | |
tree | 74881150207ae980b1703644da265fed6886d65d | |
parent | fa40bfb9e6f3bcdfe631301be2ee3ce755cbef0e (diff) | |
download | chat-00bb4799899cbbcdf48b147639dee3cee7ea199b.tar.gz chat-00bb4799899cbbcdf48b147639dee3cee7ea199b.tar.bz2 chat-00bb4799899cbbcdf48b147639dee3cee7ea199b.zip |
PLT-6090 adding ability to read license file from disk (#5895)
* PLT-6090 adding ability to read license file from disk
* Fixing unit test that fails only sometimes
* Fixing test that fails randomly
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | api/license.go | 2 | ||||
-rw-r--r-- | app/license.go | 42 | ||||
-rw-r--r-- | model/config.go | 5 | ||||
-rw-r--r-- | store/sql_webhook_store_test.go | 2 | ||||
-rw-r--r-- | utils/license.go | 27 | ||||
-rw-r--r-- | utils/license_test.go | 28 |
7 files changed, 97 insertions, 11 deletions
diff --git a/.gitignore b/.gitignore index 6ab3cf0a4..99c3a72f8 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,8 @@ node_modules /dist /webapp/dist npm-debug.log +mattermost.mattermost-license +config/mattermost.mattermost-license web/static/js/bundle*.js web/static/js/bundle*.js.map diff --git a/api/license.go b/api/license.go index ea5de20d4..0e9eb6027 100644 --- a/api/license.go +++ b/api/license.go @@ -68,6 +68,8 @@ func addLicense(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = err return } else { + app.ReloadConfig() + app.InvalidateAllCaches() c.LogAudit("success") w.Write([]byte(license.ToJson())) } diff --git a/app/license.go b/app/license.go index 1efaf85d5..6b448b19d 100644 --- a/app/license.go +++ b/app/license.go @@ -4,6 +4,7 @@ package app import ( + "os" "strings" l4g "github.com/alecthomas/log4go" @@ -21,13 +22,36 @@ func LoadLicense() { } if len(licenseId) != 26 { - l4g.Info(utils.T("mattermost.load_license.find.warn")) - return + // Lets attempt to load the file from disk since it was missing from the DB + fileName := utils.GetLicenseFileLocation(*utils.Cfg.ServiceSettings.LicenseFileLocation) + + if _, err := os.Stat(fileName); err == nil { + l4g.Info("License key has not been uploaded. Loading license key from disk at %v", fileName) + licenseBytes := utils.GetLicenseFileFromDisk(fileName) + + if success, licenseStr := utils.ValidateLicense(licenseBytes); success { + licenseFileFromDisk := model.LicenseFromJson(strings.NewReader(licenseStr)) + licenseId = licenseFileFromDisk.Id + if _, err := SaveLicense(licenseBytes); err != nil { + l4g.Info("Failed to save license key loaded from disk err=%v", err.Error()) + return + } + } else { + l4g.Error("Found license key at %v but it appears to be invalid.", fileName) + return + } + + } else { + l4g.Info(utils.T("mattermost.load_license.find.warn")) + l4g.Debug("We could not find the license key in the database or on disk at %v", fileName) + return + } } if result := <-Srv.Store.License().Get(licenseId); result.Err == nil { record := result.Data.(*model.LicenseRecord) utils.LoadLicense([]byte(record.Bytes)) + l4g.Info("License key valid unlocking enterprise features.") } else { l4g.Info(utils.T("mattermost.load_license.find.warn")) } @@ -58,16 +82,16 @@ func SaveLicense(licenseBytes []byte) (*model.License, *model.AppError) { record.Bytes = string(licenseBytes) rchan := Srv.Store.License().Save(record) - sysVar := &model.System{} - sysVar.Name = model.SYSTEM_ACTIVE_LICENSE_ID - sysVar.Value = license.Id - schan := Srv.Store.System().SaveOrUpdate(sysVar) - if result := <-rchan; result.Err != nil { RemoveLicense() return nil, model.NewLocAppError("addLicense", "api.license.add_license.save.app_error", nil, "err="+result.Err.Error()) } + sysVar := &model.System{} + sysVar.Name = model.SYSTEM_ACTIVE_LICENSE_ID + sysVar.Value = license.Id + schan := Srv.Store.System().SaveOrUpdate(sysVar) + if result := <-schan; result.Err != nil { RemoveLicense() return nil, model.NewLocAppError("addLicense", "api.license.add_license.save_active.app_error", nil, "") @@ -76,10 +100,6 @@ func SaveLicense(licenseBytes []byte) (*model.License, *model.AppError) { return nil, model.NewLocAppError("addLicense", model.INVALID_LICENSE_ERROR, nil, "") } - ReloadConfig() - - InvalidateAllCaches() - return license, nil } diff --git a/model/config.go b/model/config.go index 4486b64ad..e26bf90f1 100644 --- a/model/config.go +++ b/model/config.go @@ -111,6 +111,7 @@ const ( type ServiceSettings struct { SiteURL *string + LicenseFileLocation *string ListenAddress string ConnectionSecurity *string TLSCertFile *string @@ -497,6 +498,10 @@ func (o *Config) SetDefaults() { *o.ServiceSettings.SiteURL = SERVICE_SETTINGS_DEFAULT_SITE_URL } + if o.ServiceSettings.LicenseFileLocation == nil { + o.ServiceSettings.LicenseFileLocation = new(string) + } + if o.ServiceSettings.EnableLinkPreviews == nil { o.ServiceSettings.EnableLinkPreviews = new(bool) *o.ServiceSettings.EnableLinkPreviews = false diff --git a/store/sql_webhook_store_test.go b/store/sql_webhook_store_test.go index 6cfe36450..fbaf4bc82 100644 --- a/store/sql_webhook_store_test.go +++ b/store/sql_webhook_store_test.go @@ -5,6 +5,7 @@ package store import ( "testing" + "time" "net/http" @@ -31,6 +32,7 @@ func TestWebhookStoreUpdateIncoming(t *testing.T) { previousUpdatedAt := o1.UpdateAt o1.DisplayName = "TestHook" + time.Sleep(10 * time.Millisecond) if result := (<-store.Webhook().UpdateIncoming(o1)); result.Err != nil { t.Fatal("updation of incoming hook failed", result.Err) diff --git a/utils/license.go b/utils/license.go index 5ec94386d..f0763d741 100644 --- a/utils/license.go +++ b/utils/license.go @@ -12,6 +12,8 @@ import ( "encoding/base64" "encoding/pem" "fmt" + "io/ioutil" + "os" "strconv" "strings" @@ -112,6 +114,31 @@ func ValidateLicense(signed []byte) (bool, string) { return true, string(plaintext) } +func GetLicenseFileFromDisk(fileName string) []byte { + file, err := os.Open(fileName) + if err != nil { + l4g.Error("Failed to open license key from disk at %v err=%v", fileName, err.Error()) + return nil + } + defer file.Close() + + licenseBytes, err := ioutil.ReadAll(file) + if err != nil { + l4g.Error("Failed to read license key from disk at %v err=%v", fileName, err.Error()) + return nil + } + + return licenseBytes +} + +func GetLicenseFileLocation(fileLocation string) string { + if fileLocation == "" { + return FindDir("config") + "mattermost.mattermost-license" + } else { + return fileLocation + } +} + func getClientLicense(l *model.License) map[string]string { props := make(map[string]string) diff --git a/utils/license_test.go b/utils/license_test.go index 6508172d5..5c0122bc0 100644 --- a/utils/license_test.go +++ b/utils/license_test.go @@ -66,3 +66,31 @@ func TestClientLicenseEtag(t *testing.T) { t.Fatal("etags should not match") } } + +func TestGetLicenseFileLocation(t *testing.T) { + fileName := GetLicenseFileLocation("") + if len(fileName) == 0 { + t.Fatal("invalid default file name") + } + + fileName = GetLicenseFileLocation("mattermost.mattermost-license") + if fileName != "mattermost.mattermost-license" { + t.Fatal("invalid file name") + } +} + +func TestGetLicenseFileFromDisk(t *testing.T) { + fileBytes := GetLicenseFileFromDisk("thisfileshouldnotexist.mattermost-license") + if len(fileBytes) > 0 { + t.Fatal("invalid bytes") + } + + fileBytes = GetLicenseFileFromDisk(FindConfigFile("config.json")) + if len(fileBytes) == 0 { // a valid bytes but should be a fail license + t.Fatal("invalid bytes") + } + + if success, _ := ValidateLicense(fileBytes); success { + t.Fatal("should have been an invalid file") + } +} |