LicenseManger/sdk/go/device_sdk.go

192 lines
4.3 KiB
Go
Raw Permalink Normal View History

2024-11-16 15:59:15 +00:00
package devicesdk
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"net/http"
"time"
)
type DeviceClient struct {
baseURL string
encryptKey string
client *http.Client
}
type DeviceInfo struct {
UID string `json:"uid"`
DeviceModel string `json:"device_model"`
LicenseCode string `json:"license_code,omitempty"`
}
type ValidateResponse struct {
Status string `json:"status"`
LicenseType string `json:"license_type"`
ExpireTime time.Time `json:"expire_time"`
StartCount int `json:"start_count"`
MaxUses int `json:"max_uses"`
Timestamp int64 `json:"timestamp"`
}
type ApiResponse struct {
Code int `json:"code"`
Message string `json:"message"`
Error string `json:"error"`
Data interface{} `json:"data"`
}
func NewDeviceClient(baseURL, encryptKey string) *DeviceClient {
return &DeviceClient{
baseURL: baseURL,
encryptKey: encryptKey,
client: &http.Client{Timeout: time.Second * 30},
}
}
func (c *DeviceClient) RegisterDevice(info *DeviceInfo) error {
data, err := json.Marshal(info)
if err != nil {
return fmt.Errorf("序列化请求数据失败: %v", err)
}
resp, err := c.post("/api/devices/register", data)
if err != nil {
return err
}
if resp.Code != 0 {
return fmt.Errorf(resp.Error)
}
return nil
}
func (c *DeviceClient) ValidateDevice(uid string) (*ValidateResponse, error) {
resp, err := c.get(fmt.Sprintf("/api/devices/%s/validate", uid))
if err != nil {
return nil, err
}
if resp.Code != 0 {
return nil, fmt.Errorf(resp.Error)
}
decrypted, err := c.decryptResponse(resp.Data.(string))
if err != nil {
return nil, err
}
var validateResp ValidateResponse
if err := json.Unmarshal([]byte(decrypted), &validateResp); err != nil {
return nil, fmt.Errorf("解析响应数据失败: %v", err)
}
return &validateResp, nil
}
func (c *DeviceClient) UpdateStartCount(uid string) (int, error) {
resp, err := c.post(fmt.Sprintf("/api/devices/%s/start", uid), nil)
if err != nil {
return 0, err
}
if resp.Code != 0 {
return 0, fmt.Errorf(resp.Error)
}
data := resp.Data.(map[string]interface{})
return int(data["start_count"].(float64)), nil
}
func (c *DeviceClient) BindLicense(uid, licenseCode string) error {
data, err := json.Marshal(map[string]string{
"license_code": licenseCode,
})
if err != nil {
return fmt.Errorf("序列化请求数据失败: %v", err)
}
resp, err := c.post(fmt.Sprintf("/api/devices/%s/license", uid), data)
if err != nil {
return err
}
if resp.Code != 0 {
return fmt.Errorf(resp.Error)
}
return nil
}
// HTTP 请求辅助方法
func (c *DeviceClient) get(path string) (*ApiResponse, error) {
resp, err := c.client.Get(c.baseURL + path)
if err != nil {
return nil, fmt.Errorf("HTTP请求失败: %v", err)
}
defer resp.Body.Close()
return c.parseResponse(resp)
}
func (c *DeviceClient) post(path string, data []byte) (*ApiResponse, error) {
var resp *http.Response
var err error
if data == nil {
resp, err = c.client.Post(c.baseURL+path, "application/json", nil)
} else {
resp, err = c.client.Post(c.baseURL+path, "application/json", bytes.NewBuffer(data))
}
if err != nil {
return nil, fmt.Errorf("HTTP请求失败: %v", err)
}
defer resp.Body.Close()
return c.parseResponse(resp)
}
func (c *DeviceClient) parseResponse(resp *http.Response) (*ApiResponse, error) {
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("读取响应数据失败: %v", err)
}
var apiResp ApiResponse
if err := json.Unmarshal(body, &apiResp); err != nil {
return nil, fmt.Errorf("解析响应数据失败: %v", err)
}
return &apiResp, nil
}
func (c *DeviceClient) decryptResponse(encrypted string) (string, error) {
ciphertext, err := base64.StdEncoding.DecodeString(encrypted)
if err != nil {
return "", fmt.Errorf("base64解码失败: %v", err)
}
block, err := aes.NewCipher([]byte(c.encryptKey))
if err != nil {
return "", fmt.Errorf("创建AES cipher失败: %v", err)
}
if len(ciphertext) < aes.BlockSize {
return "", fmt.Errorf("密文长度不足")
}
iv := ciphertext[:aes.BlockSize]
ciphertext = ciphertext[aes.BlockSize:]
stream := cipher.NewCFBDecrypter(block, iv)
stream.XORKeyStream(ciphertext, ciphertext)
return string(ciphertext), nil
}