2024-01-19 17:21:51 +08:00
//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"
"golang.org/x/crypto/nacl/box"
"golang.org/x/exp/slog"
)
type TrialInfo struct {
PrivKey [ ] byte ` json:"priv_key" `
PubKey [ ] byte ` json:"pub_key" `
Secret string ` 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"
// store trial date
2024-01-19 21:40:07 +08:00
func initTrial ( ) error {
2024-01-19 17:21:51 +08:00
telData , err := logic . FetchTelemetryData ( )
if err != nil {
return err
}
if telData . Hosts > 0 || telData . Networks > 0 || telData . Users > 0 {
return nil
}
err = database . CreateTable ( trial_table_name )
if err != nil {
slog . Error ( "failed to create table" , "table name" , trial_table_name , "err" , err . Error ( ) )
return err
}
// 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 * 30 ) ,
}
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
}
trialDatesSecret , err := ncutils . BoxEncrypt ( trialDatesData , ( * [ 32 ] byte ) ( tel . TrafficKeyPub ) , ( * [ 32 ] byte ) ( t . PrivKey ) )
if err != nil {
return err
}
t . Secret = string ( 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
}
func TrialLicenseHook ( ) error {
endDate , err := getTrialEndDate ( )
if err != nil {
logger . FatalLog0 ( "failed to trial end date" , err . Error ( ) )
}
if time . Now ( ) . After ( endDate ) {
logger . FatalLog0 ( "***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`" )
}
return nil
}
// get trial date
func getTrialEndDate ( ) ( time . Time , error ) {
record , err := database . FetchRecord ( trial_table_name , trial_data_key )
if err != nil {
return time . Time { } , err
}
var trialInfo TrialInfo
err = json . Unmarshal ( [ ] byte ( record ) , & trialInfo )
if err != nil {
return time . Time { } , err
}
tel , err := logic . FetchTelemetryRecord ( )
if err != nil {
return time . Time { } , err
}
// decrypt secret
secretDecrypt , err := ncutils . BoxDecrypt ( [ ] byte ( trialInfo . Secret ) , ( * [ 32 ] byte ) ( trialInfo . PubKey ) , ( * [ 32 ] byte ) ( tel . TrafficKeyPriv ) )
if err != nil {
return time . Time { } , err
}
trialDates := TrialDates { }
err = json . Unmarshal ( secretDecrypt , & trialDates )
if err != nil {
return time . Time { } , err
}
if trialDates . TrialEndsAt . IsZero ( ) {
return time . Time { } , errors . New ( "invalid date" )
}
return trialDates . TrialEndsAt , nil
}