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.ErrBadRequest } payloadBytes, _ := json.Marshal(req) payloadB64 := base64.StdEncoding.EncodeToString(payloadBytes) signature, _ := SignPayload(payloadBytes) licenseFile := LicenseFile{ Payload: payloadB64, 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.ErrBadRequest } payloadBytes, _ := base64.StdEncoding.DecodeString(lf.Payload) var req LicenseRequest json.Unmarshal(payloadBytes, &req) if db.HasActivated(req.MachineID) { return fiber.NewError(403, "This machine is already activated.") } if !VerifySignature(&privateKey.PublicKey, payloadBytes, lf.Signature) { return fiber.NewError(401, "Invalid license signature") } licenseText := lf.Payload + "." + lf.Signature db.SaveActivation(req.MachineID, licenseText) return c.SendString("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.ErrBadRequest } payloadBytes, err := base64.StdEncoding.DecodeString(lf.Payload) if err != nil { return fiber.NewError(fiber.StatusBadRequest, "Invalid payload encoding") } // 先验证签名是否真的是对 payloadBytes 签的 if !VerifySignature(&privateKey.PublicKey, payloadBytes, lf.Signature) { return fiber.NewError(fiber.StatusUnauthorized, "Invalid license signature") } // 验证通过后再解析 payload 内容 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 { return fiber.NewError(fiber.StatusBadRequest, "Invalid expiry date") } if time.Now().After(expiry) { return fiber.NewError(fiber.StatusForbidden, "License expired") } return c.JSON(fiber.Map{"valid": true, "features": req.Features}) } }