Skip to content
This repository was archived by the owner on Nov 7, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,13 @@ func main() {
log.Fatalf("error validating configuration: %v", err)
}

licenseMod := licensing.Init(&cfg)
_ = licensing.Init(&cfg)
qmcLogChannel := logger.InitLogger(logger.Configuration{
FileLogging: cfg.Logging.FileLogging,
Path: cfg.Logging.Path,
RemoteLogDrainUrl: cfg.Logging.RemoteLogDrainUrl.ToUrl(),
Level: *cfg.Logging.Level,
ClientId: licenseMod.License.ClientID,
ClientId: "",
}, sig, doneCh)
defer logger.StdLogFile.Close()
defer logger.ErrLogFile.Close()
Expand All @@ -89,7 +89,7 @@ func main() {
var connectionPool = clickhouse.InitDBConnectionPool(&cfg)
//var connectionPool = doris.InitDBConnectionPool(&cfg)

phoneHomeAgent := telemetry.NewPhoneHomeAgent(&cfg, connectionPool, licenseMod.License.ClientID)
phoneHomeAgent := telemetry.NewPhoneHomeAgent(&cfg, connectionPool, "")
phoneHomeAgent.Start()

virtualTableStorage := persistence.NewElasticJSONDatabase(cfg.Elasticsearch, common_table.VirtualTableElasticIndexName)
Expand Down
18 changes: 8 additions & 10 deletions platform/connectors/connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@
package connectors

import (
"fmt"
"github.com/QuesmaOrg/quesma/platform/config"
"github.com/QuesmaOrg/quesma/platform/database_common"
"github.com/QuesmaOrg/quesma/platform/licensing"
"github.com/QuesmaOrg/quesma/platform/logger"
"github.com/QuesmaOrg/quesma/platform/telemetry"
quesma_api "github.com/QuesmaOrg/quesma/platform/v2/core"
Expand All @@ -27,14 +25,14 @@ func (c *ConnectorManager) GetConnector() *database_common.LogManager {
if len(c.connectors) == 0 {
panic("No connectors found")
}
conn := c.connectors[0]
if !c.connectors[0].GetConnector().IsInTransparentProxyMode() {
go func() {
if err := conn.LicensingCheck(); err != nil {
licensing.PanicWithLicenseViolation(fmt.Errorf("connector [%s] reported licensing issue: [%v]", conn.Type(), err))
}
}()
}
//conn := c.connectors[0]
//if !c.connectors[0].GetConnector().IsInTransparentProxyMode() {
// go func() {
// if err := conn.LicensingCheck(); err != nil {
// licensing.PanicWithLicenseViolation(fmt.Errorf("connector [%s] reported licensing issue: [%v]", conn.Type(), err))
// }
// }()
//}
return c.connectors[0].GetConnector()
}

Expand Down
137 changes: 66 additions & 71 deletions platform/licensing/license_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,13 @@
package licensing

import (
"bytes"
"fmt"
"github.com/goccy/go-json"
"io"
"net/http"
"time"
)

const (
obtainLicenseEndpoint = "https://licensing.quesma.com/api/license/obtain"
verifyLicenseEndpoint = "https://licensing.quesma.com/api/license/verify"
)
//const (
// obtainLicenseEndpoint = "https://licensing.quesma.com/api/license/obtain"
// verifyLicenseEndpoint = "https://licensing.quesma.com/api/license/verify"
//)

type InstallationIDPayload struct {
InstallationID string `json:"installation_id"`
Expand All @@ -25,31 +20,31 @@ type LicensePayload struct {
}

// obtainLicenseKey presents an InstallationId to the license server and receives a LicenseKey in return
func (l *LicenseModule) obtainLicenseKey() (err error) {
l.logDebug("Obtaining license key for installation ID [%s]", l.InstallationID)
var payloadBytes []byte
if payloadBytes, err = json.Marshal(InstallationIDPayload{InstallationID: l.InstallationID}); err != nil {
return err
}
resp, err := http.Post(obtainLicenseEndpoint, "application/json", bytes.NewReader(payloadBytes))
if err != nil {
return err
}
defer resp.Body.Close()

body, err := io.ReadAll(resp.Body)
if err != nil {
return err
}

var licenseResponse LicensePayload
if err = json.Unmarshal(body, &licenseResponse); err != nil {
return err
}
l.LicenseKey = []byte(licenseResponse.LicenseKey)
fmt.Printf("License key obtained and set successfully, key=[%s.....%s]\n", string(l.LicenseKey[:8]), string(l.LicenseKey[len(l.LicenseKey)-8:]))
return nil
}
//func (l *LicenseModule) obtainLicenseKey() (err error) {
// l.logDebug("Obtaining license key for installation ID [%s]", l.InstallationID)
// var payloadBytes []byte
// if payloadBytes, err = json.Marshal(InstallationIDPayload{InstallationID: l.InstallationID}); err != nil {
// return err
// }
// resp, err := http.Post(obtainLicenseEndpoint, "application/json", bytes.NewReader(payloadBytes))
// if err != nil {
// return err
// }
// defer resp.Body.Close()
//
// body, err := io.ReadAll(resp.Body)
// if err != nil {
// return err
// }
//
// var licenseResponse LicensePayload
// if err = json.Unmarshal(body, &licenseResponse); err != nil {
// return err
// }
// l.LicenseKey = []byte(licenseResponse.LicenseKey)
// fmt.Printf("License key obtained and set successfully, key=[%s.....%s]\n", string(l.LicenseKey[:8]), string(l.LicenseKey[len(l.LicenseKey)-8:]))
// return nil
//}

func FormatLicenseKey(licenseKey []byte) string {
if len(licenseKey) < 8 { // too short to be obfuscated, most probably it's invalid anyway
Expand All @@ -59,41 +54,41 @@ func FormatLicenseKey(licenseKey []byte) string {
}

// processLicense presents the license to the license server and receives an AllowList in return
func (l *LicenseModule) processLicense() error {
if fetchedLicense, err := l.fetchLicense(); err != nil {
return fmt.Errorf("license validation failed with: %v", err)
} else {
l.License = fetchedLicense
l.logDebug("Allowlist loaded successfully")
l.logDebug("%s", fetchedLicense.String())
}
if l.License.ExpirationDate.Before(time.Now()) {
return fmt.Errorf("license expired on %s", l.License.ExpirationDate)
}
return nil
}
//func (l *LicenseModule) processLicense() error {
// if fetchedLicense, err := l.fetchLicense(); err != nil {
// return fmt.Errorf("license validation failed with: %v", err)
// } else {
// l.License = fetchedLicense
// l.logDebug("Allowlist loaded successfully")
// l.logDebug("%s", fetchedLicense.String())
// }
// if l.License.ExpirationDate.Before(time.Now()) {
// return fmt.Errorf("license expired on %s", l.License.ExpirationDate)
// }
// return nil
//}

func (l *LicenseModule) fetchLicense() (a *License, err error) {
var payloadBytes []byte
if payloadBytes, err = json.Marshal(LicensePayload{LicenseKey: string(l.LicenseKey)}); err != nil {
return nil, err
}
resp, err := http.Post(verifyLicenseEndpoint, "application/json", bytes.NewReader(payloadBytes))
if resp.StatusCode == http.StatusUnauthorized {
return nil, fmt.Errorf("license key rejected by the License server")
}
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}

if err = json.Unmarshal(body, &a); err != nil {
return nil, err
} else {
return a, nil
}
}
//func (l *LicenseModule) fetchLicense() (a *License, err error) {
// var payloadBytes []byte
// if payloadBytes, err = json.Marshal(LicensePayload{LicenseKey: string(l.LicenseKey)}); err != nil {
// return nil, err
// }
// resp, err := http.Post(verifyLicenseEndpoint, "application/json", bytes.NewReader(payloadBytes))
// if resp.StatusCode == http.StatusUnauthorized {
// return nil, fmt.Errorf("license key rejected by the License server")
// }
// if err != nil {
// return nil, err
// }
// defer resp.Body.Close()
// body, err := io.ReadAll(resp.Body)
// if err != nil {
// return nil, err
// }
//
// if err = json.Unmarshal(body, &a); err != nil {
// return nil, err
// } else {
// return a, nil
// }
//}
5 changes: 3 additions & 2 deletions platform/licensing/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ import (

// License is an object returned by the license server based on the provided (and positively verified) license key
type License struct {
InstallationID string `json:"installation_id"`
ClientID string `json:"client_id"`
InstallationID string `json:"installation_id"`
// Deprecated
ClientID string `json:"client_id"` // used to be a human-readable organization name for telemetry purposes, given licensing module disabling its now irrelevant
Connectors []string `json:"connectors"`
Processors []string `json:"processors"`
ExpirationDate time.Time `json:"expiration_date"`
Expand Down
50 changes: 25 additions & 25 deletions platform/licensing/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ import (
"github.com/google/uuid"
"github.com/rs/zerolog"
"os"
"slices"
)

type LicenseModule struct {
InstallationID string
LicenseKey []byte
License *License
Config *config.QuesmaConfiguration
//Deprecated
License *License // License module has been disabled
Config *config.QuesmaConfiguration
}

const (
Expand Down Expand Up @@ -66,31 +66,31 @@ func (l *LicenseModule) Run() {
} else {
l.logInfo("License key not supplied in the configuration, will attempt to obtain temporary license with limited functionalities")
l.setInstallationID()
if err := l.obtainLicenseKey(); err != nil {
PanicWithLicenseViolation(fmt.Errorf("failed to obtain license key: %v", err))
}
}
if err := l.processLicense(); err != nil {
PanicWithLicenseViolation(fmt.Errorf("failed to process license: %v", err))
}
if err := l.validateConfig(); err != nil {
PanicWithLicenseViolation(fmt.Errorf("failed to validate configuration: %v", err))
//if err := l.obtainLicenseKey(); err != nil {
// PanicWithLicenseViolation(fmt.Errorf("failed to obtain license key: %v", err))
//}
}
//if err := l.processLicense(); err != nil {
// PanicWithLicenseViolation(fmt.Errorf("failed to process license: %v", err))
//}
//if err := l.validateConfig(); err != nil {
// PanicWithLicenseViolation(fmt.Errorf("failed to validate configuration: %v", err))
//}
}

func (l *LicenseModule) validateConfig() error {
// Check if connectors are allowed
for _, conn := range l.Config.Connectors {
// TODO remove this once hydrolix connector is fully integrated
if conn.ConnectorType == "hydrolix" {
continue
}
if !slices.Contains(l.License.Connectors, conn.ConnectorType) {
return fmt.Errorf("connector of type [%s] is not allowed within the current license", conn.ConnectorType)
}
}
return nil
}
//func (l *LicenseModule) validateConfig() error {
// // Check if connectors are allowed
// for _, conn := range l.Config.Connectors {
// // TODO remove this once hydrolix connector is fully integrated
// if conn.ConnectorType == "hydrolix" {
// continue
// }
// if !slices.Contains(l.License.Connectors, conn.ConnectorType) {
// return fmt.Errorf("connector of type [%s] is not allowed within the current license", conn.ConnectorType)
// }
// }
// return nil
//}

func (l *LicenseModule) setInstallationID() {
if l.Config.InstallationId != "" {
Expand Down
Loading