mirror of
https://github.com/xslasd/go-licensemanage.git
synced 2024-07-25 13:10:35 +08:00
137 lines
3.8 KiB
Go
137 lines
3.8 KiB
Go
package manage
|
|
|
|
import (
|
|
"crypto/sha1"
|
|
"encoding/json"
|
|
"fmt"
|
|
"hash"
|
|
"time"
|
|
)
|
|
|
|
type LicenseLimitHandler func(activationInfo ActivationInfo, data *LicenseInfo) error
|
|
|
|
type ActivationDecryptFunc func(cipherByte []byte, privateKey []byte) ([]byte, error)
|
|
type LicenseEncryptFunc func(plainText []byte, publicKey []byte) ([]byte, error)
|
|
|
|
type manage struct {
|
|
licenseLimitHandler LicenseLimitHandler
|
|
pollVerifyTime string
|
|
|
|
activationDecryptFunc ActivationDecryptFunc
|
|
licenseEncryptFunc LicenseEncryptFunc
|
|
h hash.Hash
|
|
}
|
|
type Option func(*manage)
|
|
|
|
func WithOAEPHash(h hash.Hash) Option {
|
|
return func(config *manage) {
|
|
config.h = h
|
|
}
|
|
}
|
|
|
|
// WhitPollVerifyTime Set the automatic polling time for license verification, with a default of 24 hours.
|
|
// Please use ParseDuration parses a duration string.
|
|
func WithPollVerifyTime(pollVerifyTime string) Option {
|
|
return func(config *manage) {
|
|
config.pollVerifyTime = pollVerifyTime
|
|
}
|
|
}
|
|
|
|
// WhitLicenseLimitHandler Add processors with license restrictions。
|
|
func WithLicenseLimitHandler(handler LicenseLimitHandler) Option {
|
|
return func(config *manage) {
|
|
config.licenseLimitHandler = handler
|
|
}
|
|
}
|
|
|
|
func WithLicenseEncryptFunc(fn LicenseEncryptFunc) Option {
|
|
return func(config *manage) {
|
|
config.licenseEncryptFunc = fn
|
|
}
|
|
}
|
|
func WithActivationDecryptFunc(fn ActivationDecryptFunc) Option {
|
|
return func(config *manage) {
|
|
config.activationDecryptFunc = fn
|
|
}
|
|
}
|
|
|
|
type ActivationInfo struct {
|
|
Subject string `json:"subject"`
|
|
Description string `json:"description,omitempty"`
|
|
InvitationCode string `json:"invitation_code"`
|
|
ActivationChecks map[string]any `json:"activation_checks"`
|
|
}
|
|
|
|
type LicenseInfo struct {
|
|
Subject string `json:"subject"`
|
|
Description string `json:"description,omitempty"`
|
|
IssuedTime int64 `json:"issued_time"`
|
|
ExpiryTime int64 `json:"expiry_time"`
|
|
InvitationCode string `json:"invitation_code,omitempty"`
|
|
PollVerifyTime time.Duration `json:"poll_verify_time"`
|
|
ActivationChecks map[string]any `json:"activation_checks"`
|
|
}
|
|
|
|
type RSAKeyConfig struct {
|
|
ActivationDecryptKey []byte
|
|
LicenseEncryptKey []byte
|
|
}
|
|
|
|
// GenerateLicense Generate License
|
|
// activationCode Activate the file [] byte. ExpiryTime is a millisecond timestamp, and when it is -1, it indicates that the license will never expire.
|
|
func GenerateLicense(rsaKey RSAKeyConfig, activationCode []byte, expiryTime int64, opts ...Option) ([]byte, error) {
|
|
m := new(manage)
|
|
for _, o := range opts {
|
|
o(m)
|
|
}
|
|
if m.h == nil {
|
|
m.h = sha1.New()
|
|
}
|
|
if m.licenseEncryptFunc == nil {
|
|
m.licenseEncryptFunc = m.encrypt
|
|
}
|
|
if m.activationDecryptFunc == nil {
|
|
m.activationDecryptFunc = m.decrypt
|
|
}
|
|
ActivationInfoByte, err := m.activationDecryptFunc(activationCode, rsaKey.ActivationDecryptKey)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
activationInfo := new(ActivationInfo)
|
|
err = json.Unmarshal(ActivationInfoByte, activationInfo)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
duration, err := time.ParseDuration(m.pollVerifyTime)
|
|
if err == nil {
|
|
return nil, err
|
|
}
|
|
|
|
res := new(LicenseInfo)
|
|
res.Subject = activationInfo.Subject
|
|
res.Description = activationInfo.Description
|
|
res.InvitationCode = activationInfo.InvitationCode
|
|
res.IssuedTime = time.Now().UnixMilli()
|
|
res.ExpiryTime = expiryTime
|
|
res.PollVerifyTime = duration
|
|
res.ActivationChecks = activationInfo.ActivationChecks
|
|
if m.licenseLimitHandler != nil {
|
|
err = m.licenseLimitHandler(*activationInfo, res)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
data, err := json.Marshal(res)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
resEncryptByte, err := m.licenseEncryptFunc(data, rsaKey.LicenseEncryptKey)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
fmt.Println("License generation successful!")
|
|
fmt.Println("License ExpiryTime:", res.ExpiryTime)
|
|
return resEncryptByte, nil
|
|
}
|