netmaker/pro/trial.go
the_aceix 5d02109252 fix(NET-1175): use default trial end date
this "more recent" arbitrary date is needed for hubspot to consume exported data without throwing out of date range exeptions
2024-05-03 12:52:55 +00:00

162 lines
4 KiB
Go

//go:build ee
// +build ee
package pro
import (
"crypto/rand"
"encoding/json"
"errors"
"time"
"github.com/gravitl/netmaker/database"
"github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/logic"
"github.com/gravitl/netmaker/models"
"github.com/gravitl/netmaker/netclient/ncutils"
"github.com/gravitl/netmaker/servercfg"
"golang.org/x/crypto/nacl/box"
)
type TrialInfo struct {
PrivKey []byte `json:"priv_key"`
PubKey []byte `json:"pub_key"`
Secret []byte `json:"secret"`
}
func addTrialLicenseHook() {
logic.HookManagerCh <- models.HookDetails{
Hook: TrialLicenseHook,
Interval: time.Hour,
}
}
type TrialDates struct {
TrialStartedAt time.Time `json:"trial_started_at"`
TrialEndsAt time.Time `json:"trial_ends_at"`
}
const trial_table_name = "trial"
const trial_data_key = "trialdata"
// stores trial end date
func initTrial() error {
telData := logic.FetchTelemetryData()
if telData.Hosts > 0 || telData.Networks > 0 || telData.Users > 0 {
return nil // database is already populated, so skip creating trial
}
database.CreateTable(trial_table_name)
records, err := database.FetchRecords(trial_table_name)
if err != nil && !database.IsEmptyRecord(err) {
return err
}
if len(records) > 0 {
return nil
}
// setup encryption keys
trafficPubKey, trafficPrivKey, err := box.GenerateKey(rand.Reader) // generate traffic keys
if err != nil {
return err
}
tPriv, err := ncutils.ConvertKeyToBytes(trafficPrivKey)
if err != nil {
return err
}
tPub, err := ncutils.ConvertKeyToBytes(trafficPubKey)
if err != nil {
return err
}
trialDates := TrialDates{
TrialStartedAt: time.Now(),
TrialEndsAt: time.Now().Add(time.Hour * 24 * 14),
}
t := TrialInfo{
PrivKey: tPriv,
PubKey: tPub,
}
tel, err := logic.FetchTelemetryRecord()
if err != nil {
return err
}
trialDatesData, err := json.Marshal(trialDates)
if err != nil {
return err
}
telePubKey, err := ncutils.ConvertBytesToKey(tel.TrafficKeyPub)
if err != nil {
return err
}
trialDatesSecret, err := ncutils.BoxEncrypt(trialDatesData, telePubKey, trafficPrivKey)
if err != nil {
return err
}
t.Secret = trialDatesSecret
trialData, err := json.Marshal(t)
if err != nil {
return err
}
err = database.Insert(trial_data_key, string(trialData), trial_table_name)
if err != nil {
return err
}
return nil
}
// TrialLicenseHook - hook func to check if pro trial has ended
func TrialLicenseHook() error {
endDate, err := getTrialEndDate()
if err != nil {
logger.FatalLog0("failed to trial end date", err.Error())
}
if time.Now().After(endDate) {
logger.Log(0, "***IMPORTANT: Your Trial Has Ended, to continue using pro version, please visit https://app.netmaker.io/ and create on-prem tenant to obtain a license***\nIf you wish to downgrade to community version, please run this command `/root/nm-quick.sh -d`")
err = errors.New("your trial has ended")
servercfg.ErrLicenseValidation = err
return err
}
return nil
}
// get trial date
func getTrialEndDate() (time.Time, error) {
record, err := database.FetchRecord(trial_table_name, trial_data_key)
if err != nil {
return logic.DefaultTrialEndDate, err
}
var trialInfo TrialInfo
err = json.Unmarshal([]byte(record), &trialInfo)
if err != nil {
return logic.DefaultTrialEndDate, err
}
tel, err := logic.FetchTelemetryRecord()
if err != nil {
return logic.DefaultTrialEndDate, err
}
telePrivKey, err := ncutils.ConvertBytesToKey(tel.TrafficKeyPriv)
if err != nil {
return logic.DefaultTrialEndDate, err
}
trialPubKey, err := ncutils.ConvertBytesToKey(trialInfo.PubKey)
if err != nil {
return logic.DefaultTrialEndDate, err
}
// decrypt secret
secretDecrypt, err := ncutils.BoxDecrypt(trialInfo.Secret, trialPubKey, telePrivKey)
if err != nil {
return logic.DefaultTrialEndDate, err
}
trialDates := TrialDates{}
err = json.Unmarshal(secretDecrypt, &trialDates)
if err != nil {
return logic.DefaultTrialEndDate, err
}
if trialDates.TrialEndsAt.IsZero() {
return logic.DefaultTrialEndDate, errors.New("invalid date")
}
return trialDates.TrialEndsAt, nil
}