github.com/ashishbhate/mattermost-server@v5.11.1+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().Count(model.UserCountOptions{})
    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 license != nil && license.IsExpired() {
    66  		return nil, model.NewAppError("addLicense", model.EXPIRED_LICENSE_ERROR, nil, "", http.StatusBadRequest)
    67  	}
    68  
    69  	if ok := a.SetLicense(license); !ok {
    70  		return nil, model.NewAppError("addLicense", model.EXPIRED_LICENSE_ERROR, nil, "", http.StatusBadRequest)
    71  	}
    72  
    73  	record := &model.LicenseRecord{}
    74  	record.Id = license.Id
    75  	record.Bytes = string(licenseBytes)
    76  	rchan := a.Srv.Store.License().Save(record)
    77  
    78  	if result := <-rchan; result.Err != nil {
    79  		a.RemoveLicense()
    80  		return nil, model.NewAppError("addLicense", "api.license.add_license.save.app_error", nil, "err="+result.Err.Error(), http.StatusInternalServerError)
    81  	}
    82  
    83  	sysVar := &model.System{}
    84  	sysVar.Name = model.SYSTEM_ACTIVE_LICENSE_ID
    85  	sysVar.Value = license.Id
    86  	schan := a.Srv.Store.System().SaveOrUpdate(sysVar)
    87  
    88  	if result := <-schan; result.Err != nil {
    89  		a.RemoveLicense()
    90  		return nil, model.NewAppError("addLicense", "api.license.add_license.save_active.app_error", nil, "", http.StatusInternalServerError)
    91  	}
    92  
    93  	a.ReloadConfig()
    94  	a.InvalidateAllCaches()
    95  
    96  	// start job server if necessary - this handles the edge case where a license file is uploaded, but the job server
    97  	// doesn't start until the server is restarted, which prevents the 'run job now' buttons in system console from
    98  	// functioning as expected
    99  	if *a.Config().JobSettings.RunJobs && a.Srv.Jobs != nil && a.Srv.Jobs.Workers != nil {
   100  		a.Srv.Jobs.StartWorkers()
   101  	}
   102  	if *a.Config().JobSettings.RunScheduler && a.Srv.Jobs != nil && a.Srv.Jobs.Schedulers != nil {
   103  		a.Srv.Jobs.StartSchedulers()
   104  	}
   105  
   106  	return license, nil
   107  }
   108  
   109  // License returns the currently active license or nil if the application is unlicensed.
   110  func (a *App) License() *model.License {
   111  	return a.Srv.License()
   112  }
   113  
   114  func (a *App) SetLicense(license *model.License) bool {
   115  	defer func() {
   116  		for _, listener := range a.Srv.licenseListeners {
   117  			listener()
   118  		}
   119  	}()
   120  
   121  	if license != nil {
   122  		license.Features.SetDefaults()
   123  
   124  		a.Srv.licenseValue.Store(license)
   125  		a.Srv.clientLicenseValue.Store(utils.GetClientLicense(license))
   126  		return true
   127  	}
   128  
   129  	a.Srv.licenseValue.Store((*model.License)(nil))
   130  	a.Srv.clientLicenseValue.Store(map[string]string(nil))
   131  	return false
   132  }
   133  
   134  func (a *App) ValidateAndSetLicenseBytes(b []byte) {
   135  	if success, licenseStr := utils.ValidateLicense(b); success {
   136  		license := model.LicenseFromJson(strings.NewReader(licenseStr))
   137  		a.SetLicense(license)
   138  		return
   139  	}
   140  
   141  	mlog.Warn("No valid enterprise license found")
   142  }
   143  
   144  func (a *App) SetClientLicense(m map[string]string) {
   145  	a.Srv.clientLicenseValue.Store(m)
   146  }
   147  
   148  func (a *App) ClientLicense() map[string]string {
   149  	if clientLicense, _ := a.Srv.clientLicenseValue.Load().(map[string]string); clientLicense != nil {
   150  		return clientLicense
   151  	}
   152  	return map[string]string{"IsLicensed": "false"}
   153  }
   154  
   155  func (a *App) RemoveLicense() *model.AppError {
   156  	if license, _ := a.Srv.licenseValue.Load().(*model.License); license == nil {
   157  		return nil
   158  	}
   159  
   160  	sysVar := &model.System{}
   161  	sysVar.Name = model.SYSTEM_ACTIVE_LICENSE_ID
   162  	sysVar.Value = ""
   163  
   164  	if result := <-a.Srv.Store.System().SaveOrUpdate(sysVar); result.Err != nil {
   165  		return result.Err
   166  	}
   167  
   168  	a.SetLicense(nil)
   169  	a.ReloadConfig()
   170  
   171  	a.InvalidateAllCaches()
   172  
   173  	return nil
   174  }
   175  
   176  func (s *Server) AddLicenseListener(listener func()) string {
   177  	id := model.NewId()
   178  	s.licenseListeners[id] = listener
   179  	return id
   180  }
   181  
   182  func (a *App) AddLicenseListener(listener func()) string {
   183  	id := model.NewId()
   184  	a.Srv.licenseListeners[id] = listener
   185  	return id
   186  }
   187  
   188  func (s *Server) RemoveLicenseListener(id string) {
   189  	delete(s.licenseListeners, id)
   190  }
   191  
   192  func (a *App) RemoveLicenseListener(id string) {
   193  	delete(a.Srv.licenseListeners, id)
   194  }
   195  
   196  func (a *App) GetClientLicenseEtag(useSanitized bool) string {
   197  	value := ""
   198  
   199  	lic := a.ClientLicense()
   200  
   201  	if useSanitized {
   202  		lic = a.GetSanitizedClientLicense()
   203  	}
   204  
   205  	for k, v := range lic {
   206  		value += fmt.Sprintf("%s:%s;", k, v)
   207  	}
   208  
   209  	return model.Etag(fmt.Sprintf("%x", md5.Sum([]byte(value))))
   210  }
   211  
   212  func (a *App) GetSanitizedClientLicense() map[string]string {
   213  	sanitizedLicense := make(map[string]string)
   214  
   215  	for k, v := range a.ClientLicense() {
   216  		sanitizedLicense[k] = v
   217  	}
   218  
   219  	delete(sanitizedLicense, "Id")
   220  	delete(sanitizedLicense, "Name")
   221  	delete(sanitizedLicense, "Email")
   222  	delete(sanitizedLicense, "PhoneNumber")
   223  	delete(sanitizedLicense, "IssuedAt")
   224  	delete(sanitizedLicense, "StartsAt")
   225  	delete(sanitizedLicense, "ExpiresAt")
   226  	delete(sanitizedLicense, "SkuName")
   227  	delete(sanitizedLicense, "SkuShortName")
   228  
   229  	return sanitizedLicense
   230  }