github.com/turgay/mattermost-server@v5.3.2-0.20181002173352-2945e8a2b0ce+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  	success, licenseStr := utils.ValidateLicense(licenseBytes)
    50  	if !success {
    51  		return nil, model.NewAppError("addLicense", model.INVALID_LICENSE_ERROR, nil, "", http.StatusBadRequest)
    52  	}
    53  	license := model.LicenseFromJson(strings.NewReader(licenseStr))
    54  
    55  	result := <-a.Srv.Store.User().AnalyticsUniqueUserCount("")
    56  	if result.Err != nil {
    57  		return nil, model.NewAppError("addLicense", "api.license.add_license.invalid_count.app_error", nil, result.Err.Error(), http.StatusBadRequest)
    58  	}
    59  	uniqueUserCount := result.Data.(int64)
    60  
    61  	if uniqueUserCount > int64(*license.Features.Users) {
    62  		return nil, model.NewAppError("addLicense", "api.license.add_license.unique_users.app_error", map[string]interface{}{"Users": *license.Features.Users, "Count": uniqueUserCount}, "", http.StatusBadRequest)
    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  
    89  	a.ReloadConfig()
    90  	a.InvalidateAllCaches()
    91  
    92  	// start job server if necessary - this handles the edge case where a license file is uploaded, but the job server
    93  	// doesn't start until the server is restarted, which prevents the 'run job now' buttons in system console from
    94  	// functioning as expected
    95  	if *a.Config().JobSettings.RunJobs {
    96  		a.Jobs.StartWorkers()
    97  	}
    98  	if *a.Config().JobSettings.RunScheduler {
    99  		a.Jobs.StartSchedulers()
   100  	}
   101  
   102  	return license, nil
   103  }
   104  
   105  // License returns the currently active license or nil if the application is unlicensed.
   106  func (a *App) License() *model.License {
   107  	license, _ := a.licenseValue.Load().(*model.License)
   108  	return license
   109  }
   110  
   111  func (a *App) SetLicense(license *model.License) bool {
   112  	defer func() {
   113  		for _, listener := range a.licenseListeners {
   114  			listener()
   115  		}
   116  	}()
   117  
   118  	if license != nil {
   119  		license.Features.SetDefaults()
   120  
   121  		if !license.IsExpired() {
   122  			a.licenseValue.Store(license)
   123  			a.clientLicenseValue.Store(utils.GetClientLicense(license))
   124  			return true
   125  		}
   126  	}
   127  
   128  	a.licenseValue.Store((*model.License)(nil))
   129  	a.clientLicenseValue.Store(map[string]string(nil))
   130  	return false
   131  }
   132  
   133  func (a *App) ValidateAndSetLicenseBytes(b []byte) {
   134  	if success, licenseStr := utils.ValidateLicense(b); success {
   135  		license := model.LicenseFromJson(strings.NewReader(licenseStr))
   136  		a.SetLicense(license)
   137  		return
   138  	}
   139  
   140  	mlog.Warn("No valid enterprise license found")
   141  }
   142  
   143  func (a *App) SetClientLicense(m map[string]string) {
   144  	a.clientLicenseValue.Store(m)
   145  }
   146  
   147  func (a *App) ClientLicense() map[string]string {
   148  	if clientLicense, _ := a.clientLicenseValue.Load().(map[string]string); clientLicense != nil {
   149  		return clientLicense
   150  	}
   151  	return map[string]string{"IsLicensed": "false"}
   152  }
   153  
   154  func (a *App) RemoveLicense() *model.AppError {
   155  	if license, _ := a.licenseValue.Load().(*model.License); license == nil {
   156  		return nil
   157  	}
   158  
   159  	sysVar := &model.System{}
   160  	sysVar.Name = model.SYSTEM_ACTIVE_LICENSE_ID
   161  	sysVar.Value = ""
   162  
   163  	if result := <-a.Srv.Store.System().SaveOrUpdate(sysVar); result.Err != nil {
   164  		return result.Err
   165  	}
   166  
   167  	a.SetLicense(nil)
   168  	a.ReloadConfig()
   169  
   170  	a.InvalidateAllCaches()
   171  
   172  	return nil
   173  }
   174  
   175  func (a *App) AddLicenseListener(listener func()) string {
   176  	id := model.NewId()
   177  	a.licenseListeners[id] = listener
   178  	return id
   179  }
   180  
   181  func (a *App) RemoveLicenseListener(id string) {
   182  	delete(a.licenseListeners, id)
   183  }
   184  
   185  func (a *App) GetClientLicenseEtag(useSanitized bool) string {
   186  	value := ""
   187  
   188  	lic := a.ClientLicense()
   189  
   190  	if useSanitized {
   191  		lic = a.GetSanitizedClientLicense()
   192  	}
   193  
   194  	for k, v := range lic {
   195  		value += fmt.Sprintf("%s:%s;", k, v)
   196  	}
   197  
   198  	return model.Etag(fmt.Sprintf("%x", md5.Sum([]byte(value))))
   199  }
   200  
   201  func (a *App) GetSanitizedClientLicense() map[string]string {
   202  	sanitizedLicense := make(map[string]string)
   203  
   204  	for k, v := range a.ClientLicense() {
   205  		sanitizedLicense[k] = v
   206  	}
   207  
   208  	delete(sanitizedLicense, "Id")
   209  	delete(sanitizedLicense, "Name")
   210  	delete(sanitizedLicense, "Email")
   211  	delete(sanitizedLicense, "PhoneNumber")
   212  	delete(sanitizedLicense, "IssuedAt")
   213  	delete(sanitizedLicense, "StartsAt")
   214  	delete(sanitizedLicense, "ExpiresAt")
   215  
   216  	return sanitizedLicense
   217  }