license-server/license/service.go

117 lines
3.3 KiB
Go

package license
import (
"encoding/base64"
"encoding/json"
"license-server/storage"
"time"
"github.com/gofiber/fiber/v2"
)
func GenerateLicenseHandler(db storage.Database) fiber.Handler {
return func(c *fiber.Ctx) error {
var req LicenseRequest
if err := c.BodyParser(&req); err != nil {
return fiber.NewError(fiber.StatusBadRequest, "Invalid request body")
}
if req.MachineID == "" || req.Expiry == "" {
return fiber.NewError(fiber.StatusBadRequest, "Missing required fields")
}
payloadBytes, err := json.Marshal(req)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, "Failed to encode payload")
}
signature, err := SignPayload(payloadBytes)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, "Signing failed")
}
licenseFile := LicenseFile{
Payload: base64.StdEncoding.EncodeToString(payloadBytes),
Signature: signature,
}
return c.JSON(licenseFile)
}
}
func ActivateLicenseHandler(db storage.Database) fiber.Handler {
return func(c *fiber.Ctx) error {
var lf LicenseFile
if err := c.BodyParser(&lf); err != nil {
return fiber.NewError(fiber.StatusBadRequest, "Invalid license format")
}
payloadBytes, err := base64.StdEncoding.DecodeString(lf.Payload)
if err != nil {
return fiber.NewError(fiber.StatusBadRequest, "Invalid base64 payload")
}
if !VerifySignature(GetPublicKey(), payloadBytes, lf.Signature) {
return fiber.NewError(fiber.StatusUnauthorized, "Invalid license signature")
}
var req LicenseRequest
if err := json.Unmarshal(payloadBytes, &req); err != nil {
return fiber.NewError(fiber.StatusBadRequest, "Malformed payload")
}
if req.MachineID == "" {
return fiber.NewError(fiber.StatusBadRequest, "Missing machine ID")
}
if db.HasActivated(req.MachineID) {
return fiber.NewError(fiber.StatusForbidden, "This machine is already activated")
}
expiry, err := time.Parse("2006-01-02", req.Expiry)
if err != nil || time.Now().After(expiry) {
return fiber.NewError(fiber.StatusForbidden, "License is invalid or expired")
}
// 绑定激活记录
db.SaveActivation(req.MachineID, lf.Payload+"."+lf.Signature)
return c.JSON(fiber.Map{"status": "success", "message": "License activated successfully"})
}
}
func ValidateLicenseHandler(db storage.Database) fiber.Handler {
return func(c *fiber.Ctx) error {
var lf LicenseFile
if err := c.BodyParser(&lf); err != nil {
return fiber.NewError(fiber.StatusBadRequest, "Invalid license format")
}
payloadBytes, err := base64.StdEncoding.DecodeString(lf.Payload)
if err != nil {
return fiber.NewError(fiber.StatusBadRequest, "Invalid base64 payload")
}
if !VerifySignature(GetPublicKey(), payloadBytes, lf.Signature) {
return fiber.NewError(fiber.StatusUnauthorized, "Invalid license signature")
}
var req LicenseRequest
if err := json.Unmarshal(payloadBytes, &req); err != nil {
return fiber.NewError(fiber.StatusBadRequest, "Malformed payload")
}
expiry, err := time.Parse("2006-01-02", req.Expiry)
if err != nil || time.Now().After(expiry) {
return fiber.NewError(fiber.StatusForbidden, "License expired")
}
return c.JSON(fiber.Map{
"valid": true,
"features": req.Features,
"machine": req.MachineID,
"expiry": req.Expiry,
})
}
}