This commit is contained in:
parent
fcb6c480eb
commit
e0286c29b8
|
|
@ -1,78 +1,80 @@
|
||||||
package license
|
package license
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/gofiber/fiber/v2"
|
"license-server/storage"
|
||||||
"license-server/storage"
|
"time"
|
||||||
"time"
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GenerateLicenseHandler(db storage.Database) fiber.Handler {
|
func GenerateLicenseHandler(db storage.Database) fiber.Handler {
|
||||||
return func(c *fiber.Ctx) error {
|
return func(c *fiber.Ctx) error {
|
||||||
var req LicenseRequest
|
var req LicenseRequest
|
||||||
if err := c.BodyParser(&req); err != nil {
|
if err := c.BodyParser(&req); err != nil {
|
||||||
return fiber.ErrBadRequest
|
return fiber.ErrBadRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
payloadBytes, _ := json.Marshal(req)
|
payloadBytes, _ := json.Marshal(req)
|
||||||
payloadB64 := base64.StdEncoding.EncodeToString(payloadBytes)
|
payloadB64 := base64.StdEncoding.EncodeToString(payloadBytes)
|
||||||
signature, _ := SignPayload(payloadBytes)
|
signature, _ := SignPayload(payloadBytes)
|
||||||
|
|
||||||
licenseFile := LicenseFile{
|
licenseFile := LicenseFile{
|
||||||
Payload: payloadB64,
|
Payload: payloadB64,
|
||||||
Signature: signature,
|
Signature: signature,
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.JSON(licenseFile)
|
return c.JSON(licenseFile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ActivateLicenseHandler(db storage.Database) fiber.Handler {
|
func ActivateLicenseHandler(db storage.Database) fiber.Handler {
|
||||||
return func(c *fiber.Ctx) error {
|
return func(c *fiber.Ctx) error {
|
||||||
var lf LicenseFile
|
var lf LicenseFile
|
||||||
if err := c.BodyParser(&lf); err != nil {
|
if err := c.BodyParser(&lf); err != nil {
|
||||||
return fiber.ErrBadRequest
|
return fiber.ErrBadRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
payloadBytes, _ := base64.StdEncoding.DecodeString(lf.Payload)
|
payloadBytes, _ := base64.StdEncoding.DecodeString(lf.Payload)
|
||||||
var req LicenseRequest
|
var req LicenseRequest
|
||||||
json.Unmarshal(payloadBytes, &req)
|
json.Unmarshal(payloadBytes, &req)
|
||||||
|
|
||||||
if db.HasActivated(req.MachineID) {
|
if db.HasActivated(req.MachineID) {
|
||||||
return fiber.NewError(403, "This machine is already activated.")
|
return fiber.NewError(403, "This machine is already activated.")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !VerifySignature(&privateKey.PublicKey, payloadBytes, lf.Signature) {
|
if !VerifySignature(&privateKey.PublicKey, payloadBytes, lf.Signature) {
|
||||||
return fiber.NewError(401, "Invalid license signature")
|
return fiber.NewError(401, "Invalid license signature")
|
||||||
}
|
}
|
||||||
|
|
||||||
db.SaveActivation(req.MachineID, lf)
|
licenseText := lf.Payload + "." + lf.Signature
|
||||||
return c.SendString("License activated successfully.")
|
db.SaveActivation(req.MachineID, licenseText)
|
||||||
}
|
|
||||||
|
return c.SendString("License activated successfully.")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ValidateLicenseHandler(db storage.Database) fiber.Handler {
|
func ValidateLicenseHandler(db storage.Database) fiber.Handler {
|
||||||
return func(c *fiber.Ctx) error {
|
return func(c *fiber.Ctx) error {
|
||||||
var lf LicenseFile
|
var lf LicenseFile
|
||||||
if err := c.BodyParser(&lf); err != nil {
|
if err := c.BodyParser(&lf); err != nil {
|
||||||
return fiber.ErrBadRequest
|
return fiber.ErrBadRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
payloadBytes, _ := base64.StdEncoding.DecodeString(lf.Payload)
|
payloadBytes, _ := base64.StdEncoding.DecodeString(lf.Payload)
|
||||||
var req LicenseRequest
|
var req LicenseRequest
|
||||||
json.Unmarshal(payloadBytes, &req)
|
json.Unmarshal(payloadBytes, &req)
|
||||||
|
|
||||||
if !VerifySignature(&privateKey.PublicKey, payloadBytes, lf.Signature) {
|
if !VerifySignature(&privateKey.PublicKey, payloadBytes, lf.Signature) {
|
||||||
return fiber.NewError(401, "Invalid license signature")
|
return fiber.NewError(401, "Invalid license signature")
|
||||||
}
|
}
|
||||||
|
|
||||||
expiry, _ := time.Parse("2006-01-02", req.Expiry)
|
expiry, _ := time.Parse("2006-01-02", req.Expiry)
|
||||||
if time.Now().After(expiry) {
|
if time.Now().After(expiry) {
|
||||||
return fiber.NewError(403, "License expired")
|
return fiber.NewError(403, "License expired")
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.JSON(fiber.Map{"valid": true, "features": req.Features})
|
return c.JSON(fiber.Map{"valid": true, "features": req.Features})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,35 +1,34 @@
|
||||||
package storage
|
package storage
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
_ "github.com/mattn/go-sqlite3"
|
|
||||||
"license-server/license"
|
_ "github.com/mattn/go-sqlite3"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Database struct {
|
type Database struct {
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitDB() Database {
|
func InitDB() Database {
|
||||||
db, _ := sql.Open("sqlite3", "./license.db")
|
db, _ := sql.Open("sqlite3", "./license.db")
|
||||||
db.Exec(`CREATE TABLE IF NOT EXISTS activations (
|
db.Exec(`CREATE TABLE IF NOT EXISTS activations (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
machine_id TEXT UNIQUE,
|
machine_id TEXT UNIQUE,
|
||||||
license TEXT,
|
license TEXT,
|
||||||
activated INTEGER
|
activated INTEGER
|
||||||
)`)
|
)`)
|
||||||
return Database{db}
|
return Database{db}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d Database) HasActivated(machineID string) bool {
|
func (d Database) HasActivated(machineID string) bool {
|
||||||
row := d.db.QueryRow("SELECT activated FROM activations WHERE machine_id = ?", machineID)
|
row := d.db.QueryRow("SELECT activated FROM activations WHERE machine_id = ?", machineID)
|
||||||
var activated int
|
var activated int
|
||||||
err := row.Scan(&activated)
|
err := row.Scan(&activated)
|
||||||
return err == nil && activated == 1
|
return err == nil && activated == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d Database) SaveActivation(machineID string, lf license.LicenseFile) {
|
func (d Database) SaveActivation(machineID string, licenseText string) {
|
||||||
d.db.Exec("INSERT OR REPLACE INTO activations(machine_id, license, activated) VALUES (?, ?, 1)",
|
d.db.Exec("INSERT OR REPLACE INTO activations(machine_id, license, activated) VALUES (?, ?, 1)",
|
||||||
machineID, lf.Payload+"."+lf.Signature)
|
machineID, licenseText)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue