mirror of
https://gitee.com/mirrors/AllinSSL.git
synced 2026-03-08 07:41:10 +08:00
括彩云CDN插件
This commit is contained in:
165
plugins/kuocai/action.go
Normal file
165
plugins/kuocai/action.go
Normal file
@@ -0,0 +1,165 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type LoginInfo struct {
|
||||
account string
|
||||
password string
|
||||
}
|
||||
type LoginResponse struct {
|
||||
Code string
|
||||
Message string
|
||||
Data string
|
||||
Success bool
|
||||
}
|
||||
|
||||
type HTTPSConfig struct {
|
||||
HTTPSStatus string `json:"https_status"`
|
||||
CertificateSource string `json:"certificate_source"`
|
||||
CertificateName string `json:"certificate_name"`
|
||||
CertificateValue string `json:"certificate_value"`
|
||||
PrivateKey string `json:"private_key"`
|
||||
}
|
||||
|
||||
type DeployConfig struct {
|
||||
DomainID string `json:"doMainId"`
|
||||
HTTPS HTTPSConfig `json:"https"`
|
||||
}
|
||||
|
||||
func randomString(n int) string {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||
b := make([]byte, n)
|
||||
for i := range b {
|
||||
b[i] = charset[rand.Intn(len(charset))]
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
const baseUrl = "https://www.kuocaiyun.com/"
|
||||
|
||||
func login(loginInfo LoginInfo) (string, error) {
|
||||
loginUrl := baseUrl + "login/loginUser"
|
||||
formData := url.Values{}
|
||||
formData.Set("userAccount", loginInfo.account)
|
||||
formData.Set("userPwd", loginInfo.password)
|
||||
formData.Set("remember", "true")
|
||||
resp, err := http.Post(loginUrl, "application/x-www-form-urlencoded", strings.NewReader(formData.Encode()))
|
||||
const emptyString = ""
|
||||
if err != nil {
|
||||
outputError("请求失败", err)
|
||||
return emptyString, err
|
||||
}
|
||||
if resp.StatusCode != 200 {
|
||||
return emptyString, errors.New("请求失败:" + string(rune(resp.StatusCode)))
|
||||
}
|
||||
defer func(Body io.ReadCloser) {
|
||||
err := Body.Close()
|
||||
if err != nil {
|
||||
outputError("关闭响应流失败", err)
|
||||
}
|
||||
}(resp.Body)
|
||||
// 读取响应体
|
||||
var loginResp LoginResponse
|
||||
if err := json.NewDecoder(resp.Body).Decode(&loginResp); err != nil {
|
||||
outputError("解析登录请求结果失败", err)
|
||||
return emptyString, err
|
||||
}
|
||||
if !loginResp.Success || loginResp.Data == "" {
|
||||
return emptyString, errors.New("登录请求失败:" + loginResp.Message)
|
||||
}
|
||||
return loginResp.Data, nil
|
||||
}
|
||||
|
||||
func deployCert(token string, domainId string, certKey string, certValue string) (map[string]interface{}, error) {
|
||||
deployUrl := baseUrl + "CdnDomainHttps/httpsConfiguration"
|
||||
params := DeployConfig{
|
||||
DomainID: domainId,
|
||||
HTTPS: HTTPSConfig{
|
||||
HTTPSStatus: "on",
|
||||
CertificateSource: "0",
|
||||
CertificateName: "cert_" + randomString(13),
|
||||
CertificateValue: certValue,
|
||||
PrivateKey: certKey,
|
||||
},
|
||||
}
|
||||
// 序列化参数
|
||||
jsonData, err := json.Marshal(params)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("JSON序列化失败: %v", err)
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", deployUrl, strings.NewReader(string(jsonData)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("Cookie", "kuocai_cdn_token="+token)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("HTTP请求失败: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// 解析响应
|
||||
var result map[string]interface{}
|
||||
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
|
||||
return nil, fmt.Errorf("响应解析失败: %v", err)
|
||||
}
|
||||
if !result["success"].(bool) {
|
||||
return result, fmt.Errorf("更新证书失败")
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func Upload(cfg map[string]any) (*Response, error) {
|
||||
if cfg == nil {
|
||||
return nil, fmt.Errorf("config cannot be nil")
|
||||
}
|
||||
certStr, ok := cfg["cert"].(string)
|
||||
if !ok || certStr == "" {
|
||||
return nil, fmt.Errorf("cert is required and must be a string")
|
||||
}
|
||||
keyStr, ok := cfg["key"].(string)
|
||||
if !ok || keyStr == "" {
|
||||
return nil, fmt.Errorf("key is required and must be a string")
|
||||
}
|
||||
username, ok := cfg["username"].(string)
|
||||
if !ok || username == "" {
|
||||
return nil, fmt.Errorf("username is required and must be a string")
|
||||
}
|
||||
password, ok := cfg["password"].(string)
|
||||
if !ok || password == "" {
|
||||
return nil, fmt.Errorf("password is required and must be a string")
|
||||
}
|
||||
domainId, ok := cfg["domainId"].(string)
|
||||
if !ok || domainId == "" {
|
||||
return nil, fmt.Errorf("domainId is required and must be a string")
|
||||
}
|
||||
token, err := login(LoginInfo{account: username, password: password})
|
||||
if err != nil || token == "" {
|
||||
return nil, fmt.Errorf("fetch token failed, err %v", err)
|
||||
}
|
||||
res, err := deployCert(token, domainId, keyStr, certStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Response{
|
||||
Status: "success",
|
||||
Message: "success",
|
||||
Result: res,
|
||||
}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user