mirror of https://github.com/allinssl/allinssl
166 lines
4.3 KiB
Go
166 lines
4.3 KiB
Go
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
|
|
}
|