迁移并重构项目,优化了执行流程
This commit is contained in:
		
							
								
								
									
										57
									
								
								internal/class/Acme/Check.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								internal/class/Acme/Check.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,57 @@
 | 
			
		||||
package Acme
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"SafeLine-Acme/internal/app/logger"
 | 
			
		||||
	"reflect"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (acme *Object) CheckFile() bool {
 | 
			
		||||
	var flag = true
 | 
			
		||||
	if acme.Email == "" {
 | 
			
		||||
		logger.Warning.Printf("未设置 %s证书申请邮箱%s: 请检查配置文件中的 %sAcme.Email%s 参数", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset)
 | 
			
		||||
		flag = false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	v := reflect.ValueOf(acme.DNSProvider)
 | 
			
		||||
	var dns = true
 | 
			
		||||
	for i := 0; i < v.NumField(); i++ {
 | 
			
		||||
		field := v.Field(i)
 | 
			
		||||
		if field.Kind() == reflect.Struct {
 | 
			
		||||
			for ii := 0; ii < field.NumField(); ii++ {
 | 
			
		||||
				if field.Field(ii).String() != "" {
 | 
			
		||||
					dns = false
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if dns {
 | 
			
		||||
		logger.Warning.Printf("未设置 %sDNS服务提供商%s: 请检查配置文件中的 %sAcme.DNSProvider%s 参数", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset)
 | 
			
		||||
	}
 | 
			
		||||
	return flag
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (acme *Object) CheckCommand() bool {
 | 
			
		||||
	var flag = true
 | 
			
		||||
	if acme.Email == "" {
 | 
			
		||||
		logger.Warning.Printf("未设置 %s证书申请邮箱%s: 请检查命令中的 %s-e%s 参数", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset)
 | 
			
		||||
		flag = false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	v := reflect.ValueOf(acme.DNSProvider).Elem()
 | 
			
		||||
 | 
			
		||||
	var dns = true
 | 
			
		||||
	for i := 0; i < v.NumField(); i++ {
 | 
			
		||||
		field := v.Field(i)
 | 
			
		||||
		if field.Kind() == reflect.Struct {
 | 
			
		||||
			for ii := 0; ii < field.NumField(); ii++ {
 | 
			
		||||
				if field.Field(ii).String() != "" {
 | 
			
		||||
					dns = false
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if dns {
 | 
			
		||||
		logger.Warning.Printf("未设置 %sDNS服务提供商%s: 请检查命令中的 %s-k%s 参数", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset)
 | 
			
		||||
	}
 | 
			
		||||
	return flag
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								internal/class/Acme/Method.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								internal/class/Acme/Method.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
			
		||||
package Acme
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (acme *Object) EmailVerify() bool {
 | 
			
		||||
	var EmailRegex = regexp.MustCompile(`^[a-zA-Z0-9.!#$%&'*+/=?^_{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$`)
 | 
			
		||||
	email := strings.TrimSpace(acme.Email)
 | 
			
		||||
	if len(email) < 3 || len(email) > 254 {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	return EmailRegex.MatchString(email)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (acme *Object) DNSProviderVerify() bool {
 | 
			
		||||
	acme.DNSProvider.Choose()
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										10
									
								
								internal/class/Acme/Object.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								internal/class/Acme/Object.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,10 @@
 | 
			
		||||
package Acme
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"SafeLine-Acme/internal/class/DNSProvider"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Object struct {
 | 
			
		||||
	Email       string             `json:"Email"`
 | 
			
		||||
	DNSProvider DNSProvider.Object `json:"DNSProvider"`
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										107
									
								
								internal/class/Config/Method.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								internal/class/Config/Method.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,107 @@
 | 
			
		||||
package Config
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"SafeLine-Acme/internal/app/logger"
 | 
			
		||||
	"SafeLine-Acme/internal/class/Acme"
 | 
			
		||||
	"SafeLine-Acme/internal/class/DNSProvider"
 | 
			
		||||
	"SafeLine-Acme/internal/class/SafeLine"
 | 
			
		||||
	"SafeLine-Acme/pkg/utils"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"flag"
 | 
			
		||||
	"log"
 | 
			
		||||
	"os"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (config *Object) Read(path string) {
 | 
			
		||||
	data, err := os.ReadFile(path)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logger.Error.Printf("配置文件读取失败: %s%s%s", logger.Red, err, logger.Reset)
 | 
			
		||||
		os.Exit(0)
 | 
			
		||||
	}
 | 
			
		||||
	err = json.Unmarshal(data, &config)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logger.Error.Printf("配置文件读取失败: %s%s%s", logger.Red, err, logger.Reset)
 | 
			
		||||
		os.Exit(0)
 | 
			
		||||
	}
 | 
			
		||||
	config.CheckFile()
 | 
			
		||||
}
 | 
			
		||||
func (config *Object) Write(path string) {
 | 
			
		||||
	data, _ := json.MarshalIndent(config, "", "	")
 | 
			
		||||
	_ = os.WriteFile(path, data, 0644)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (config *Object) Command() {
 | 
			
		||||
	var host, apiToken, email *string
 | 
			
		||||
	var days, concurrency *int
 | 
			
		||||
 | 
			
		||||
	host = flag.String("h", "172.22.222.4:1443", "-h <host>")
 | 
			
		||||
	apiToken = flag.String("t", "", "-t <apiToken>")
 | 
			
		||||
	days = flag.Int("d", 30, "-t <days>")
 | 
			
		||||
	concurrency = flag.Int("c", 3, "-c <concurrency>")
 | 
			
		||||
	email = flag.String("e", "", "-e <email>")
 | 
			
		||||
	kvp := flag.String("kv", "", "-kv <key=value>,<key=value>...")
 | 
			
		||||
	flag.Parse()
 | 
			
		||||
 | 
			
		||||
	var KVP = make(utils.KVPair)
 | 
			
		||||
	if *kvp != "" {
 | 
			
		||||
		KVP.Set(*kvp)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	config.Days = *days
 | 
			
		||||
	config.Concurrency = *concurrency
 | 
			
		||||
	config.Server = SafeLine.Object{
 | 
			
		||||
		Host:     *host,
 | 
			
		||||
		ApiToken: *apiToken,
 | 
			
		||||
	}
 | 
			
		||||
	config.Acme = Acme.Object{
 | 
			
		||||
		Email: *email,
 | 
			
		||||
		DNSProvider: DNSProvider.Object{
 | 
			
		||||
			TencentCloud: DNSProvider.TencentCloud{
 | 
			
		||||
				SecretID:  KVP["SecretID"],
 | 
			
		||||
				SecretKey: KVP["SecretKey"],
 | 
			
		||||
			},
 | 
			
		||||
			AliCloud: DNSProvider.AliCloud{
 | 
			
		||||
				AccessKeyId:     KVP["AccessKeyId"],
 | 
			
		||||
				AccessKeySecret: KVP["AccessKeySecret"],
 | 
			
		||||
				RAMRole:         KVP["RAMRole"],
 | 
			
		||||
				STSToken:        KVP["STSToken"],
 | 
			
		||||
			},
 | 
			
		||||
			HuaweiCloud: DNSProvider.HuaweiCloud{
 | 
			
		||||
				AccessKeyId:     KVP["AccessKeyId"],
 | 
			
		||||
				Region:          KVP["Region"],
 | 
			
		||||
				SecretAccessKey: KVP["SecretAccessKey"],
 | 
			
		||||
			},
 | 
			
		||||
			WestCN: DNSProvider.WestCN{
 | 
			
		||||
				Username: KVP["Username"],
 | 
			
		||||
				Password: KVP["Password"],
 | 
			
		||||
			},
 | 
			
		||||
			RainYun: DNSProvider.RainYun{
 | 
			
		||||
				ApiKey: KVP["ApiKey"],
 | 
			
		||||
			},
 | 
			
		||||
			Dode: DNSProvider.Dode{
 | 
			
		||||
				Token: KVP["Token"],
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	config.CheckCommand()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (config *Object) CheckFile() {
 | 
			
		||||
	a := config.Server.CheckFile()
 | 
			
		||||
	b := config.Acme.CheckFile()
 | 
			
		||||
	if !a || !b {
 | 
			
		||||
		log.Printf("配置检查完毕,请检查相关配置后重新运行!")
 | 
			
		||||
		os.Exit(0)
 | 
			
		||||
	}
 | 
			
		||||
	log.Printf("配置检查完毕,即将开始更新证书!")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (config *Object) CheckCommand() {
 | 
			
		||||
	a := config.Server.CheckCommand()
 | 
			
		||||
	b := config.Acme.CheckCommand()
 | 
			
		||||
	if !a || !b {
 | 
			
		||||
		log.Printf("配置检查完毕,请检查相关配置后重新运行!")
 | 
			
		||||
		os.Exit(0)
 | 
			
		||||
	}
 | 
			
		||||
	log.Printf("配置检查完毕,即将开始更新证书!")
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										13
									
								
								internal/class/Config/Object.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								internal/class/Config/Object.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,13 @@
 | 
			
		||||
package Config
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"SafeLine-Acme/internal/class/Acme"
 | 
			
		||||
	"SafeLine-Acme/internal/class/SafeLine"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Object struct {
 | 
			
		||||
	Concurrency int             `json:"Concurrency"`
 | 
			
		||||
	Days        int             `json:"Days"`
 | 
			
		||||
	Server      SafeLine.Object `json:"Server"`
 | 
			
		||||
	Acme        Acme.Object     `json:"Acme"`
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										49
									
								
								internal/class/Config/default.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								internal/class/Config/default.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,49 @@
 | 
			
		||||
package Config
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"SafeLine-Acme/internal/class/Acme"
 | 
			
		||||
	"SafeLine-Acme/internal/class/DNSProvider"
 | 
			
		||||
	"SafeLine-Acme/internal/class/SafeLine"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (config *Object) Default() {
 | 
			
		||||
	a := Object{
 | 
			
		||||
		Concurrency: 3,
 | 
			
		||||
		Days:        15,
 | 
			
		||||
		Server: SafeLine.Object{
 | 
			
		||||
			Host:     "192.168.1.4:1443",
 | 
			
		||||
			ApiToken: "xxx",
 | 
			
		||||
		},
 | 
			
		||||
		Acme: Acme.Object{
 | 
			
		||||
			Email: "xxx",
 | 
			
		||||
			DNSProvider: DNSProvider.Object{
 | 
			
		||||
				TencentCloud: DNSProvider.TencentCloud{
 | 
			
		||||
					SecretID:  "xxx",
 | 
			
		||||
					SecretKey: "xxx",
 | 
			
		||||
				},
 | 
			
		||||
				AliCloud: DNSProvider.AliCloud{
 | 
			
		||||
					AccessKeyId:     "xxx",
 | 
			
		||||
					AccessKeySecret: "xxx",
 | 
			
		||||
					RAMRole:         "xxx(可选)",
 | 
			
		||||
					STSToken:        "xxx(可选)",
 | 
			
		||||
				},
 | 
			
		||||
				HuaweiCloud: DNSProvider.HuaweiCloud{
 | 
			
		||||
					AccessKeyId:     "xxx",
 | 
			
		||||
					Region:          "xxx",
 | 
			
		||||
					SecretAccessKey: "xxx",
 | 
			
		||||
				},
 | 
			
		||||
				WestCN: DNSProvider.WestCN{
 | 
			
		||||
					Username: "xxx",
 | 
			
		||||
					Password: "xxx",
 | 
			
		||||
				},
 | 
			
		||||
				RainYun: DNSProvider.RainYun{
 | 
			
		||||
					ApiKey: "xxx",
 | 
			
		||||
				},
 | 
			
		||||
				Dode: DNSProvider.Dode{
 | 
			
		||||
					Token: "xxx",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	a.Write("./config.json")
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										60
									
								
								internal/class/DNSProvider/Method.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								internal/class/DNSProvider/Method.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,60 @@
 | 
			
		||||
package DNSProvider
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/go-acme/lego/v4/challenge"
 | 
			
		||||
	"github.com/go-acme/lego/v4/providers/dns/alidns"
 | 
			
		||||
	"github.com/go-acme/lego/v4/providers/dns/dode"
 | 
			
		||||
	"github.com/go-acme/lego/v4/providers/dns/huaweicloud"
 | 
			
		||||
	"github.com/go-acme/lego/v4/providers/dns/rainyun"
 | 
			
		||||
	"github.com/go-acme/lego/v4/providers/dns/tencentcloud"
 | 
			
		||||
	"github.com/go-acme/lego/v4/providers/dns/westcn"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (tencent TencentCloud) Provider() (challenge.Provider, error) {
 | 
			
		||||
	cfg := tencentcloud.NewDefaultConfig()
 | 
			
		||||
	cfg.SecretID = tencent.SecretID
 | 
			
		||||
	cfg.SecretKey = tencent.SecretKey
 | 
			
		||||
	p, err := tencentcloud.NewDNSProviderConfig(cfg)
 | 
			
		||||
	return p, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ali AliCloud) Provider() (challenge.Provider, error) {
 | 
			
		||||
	cfg := alidns.NewDefaultConfig()
 | 
			
		||||
	cfg.SecurityToken = ali.STSToken
 | 
			
		||||
	cfg.SecretKey = ali.AccessKeySecret
 | 
			
		||||
	cfg.RAMRole = ali.RAMRole
 | 
			
		||||
	cfg.APIKey = ali.AccessKeyId
 | 
			
		||||
	p, err := alidns.NewDNSProviderConfig(cfg)
 | 
			
		||||
	return p, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (huawei HuaweiCloud) Provider() (challenge.Provider, error) {
 | 
			
		||||
	cfg := huaweicloud.NewDefaultConfig()
 | 
			
		||||
	cfg.Region = huawei.Region
 | 
			
		||||
	cfg.AccessKeyID = huawei.AccessKeyId
 | 
			
		||||
	cfg.SecretAccessKey = huawei.SecretAccessKey
 | 
			
		||||
	p, err := huaweicloud.NewDNSProviderConfig(cfg)
 | 
			
		||||
	return p, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (west WestCN) Provider() (challenge.Provider, error) {
 | 
			
		||||
	cfg := westcn.NewDefaultConfig()
 | 
			
		||||
	cfg.Username = west.Username
 | 
			
		||||
	cfg.Password = west.Password
 | 
			
		||||
	p, err := westcn.NewDNSProviderConfig(cfg)
 | 
			
		||||
	return p, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (rain RainYun) Provider() (challenge.Provider, error) {
 | 
			
		||||
	cfg := rainyun.NewDefaultConfig()
 | 
			
		||||
	cfg.APIKey = rain.ApiKey
 | 
			
		||||
	p, err := rainyun.NewDNSProviderConfig(cfg)
 | 
			
		||||
	return p, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (Dode Dode) Provider() (challenge.Provider, error) {
 | 
			
		||||
	cfg := dode.NewDefaultConfig()
 | 
			
		||||
	cfg.Token = Dode.Token
 | 
			
		||||
	p, err := dode.NewDNSProviderConfig(cfg)
 | 
			
		||||
	return p, err
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										43
									
								
								internal/class/DNSProvider/Object.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								internal/class/DNSProvider/Object.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,43 @@
 | 
			
		||||
package DNSProvider
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"reflect"
 | 
			
		||||
 | 
			
		||||
	"github.com/go-acme/lego/v4/challenge"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Object struct {
 | 
			
		||||
	TencentCloud TencentCloud `json:"TencentCloud,omitempty"`
 | 
			
		||||
	AliCloud     AliCloud     `json:"AliCloud,omitempty"`
 | 
			
		||||
	HuaweiCloud  HuaweiCloud  `json:"HuaweiCloud,omitempty"`
 | 
			
		||||
	WestCN       WestCN       `json:"WestCN,omitempty"`
 | 
			
		||||
	RainYun      RainYun      `json:"RainYun,omitempty"`
 | 
			
		||||
	Dode         Dode         `json:"Dode,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (dnsProvider *Object) Choose() ([]challenge.Provider, []error) {
 | 
			
		||||
 | 
			
		||||
	var Providers []challenge.Provider
 | 
			
		||||
	var Errors []error
 | 
			
		||||
	v := reflect.ValueOf(dnsProvider).Elem()
 | 
			
		||||
 | 
			
		||||
	for i := 0; i < v.NumField(); i++ {
 | 
			
		||||
		field := v.Field(i)
 | 
			
		||||
		if field.Kind() == reflect.Struct {
 | 
			
		||||
			for ii := 0; ii < field.NumField(); ii++ {
 | 
			
		||||
				if field.Field(ii).String() != "" {
 | 
			
		||||
					method, _ := field.Type().MethodByName("Provider")
 | 
			
		||||
					results := method.Func.Call([]reflect.Value{field})
 | 
			
		||||
					err, _ := results[1].Interface().(error)
 | 
			
		||||
					if err != nil {
 | 
			
		||||
						Errors = append(Errors, err)
 | 
			
		||||
					} else {
 | 
			
		||||
						Providers = append(Providers, results[0].Interface().(challenge.Provider))
 | 
			
		||||
					}
 | 
			
		||||
					break
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return Providers, Errors
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										32
									
								
								internal/class/DNSProvider/Objects.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								internal/class/DNSProvider/Objects.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,32 @@
 | 
			
		||||
package DNSProvider
 | 
			
		||||
 | 
			
		||||
type TencentCloud struct {
 | 
			
		||||
	SecretID  string `json:"SecretId,omitempty"`
 | 
			
		||||
	SecretKey string `json:"SecretKey,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type AliCloud struct {
 | 
			
		||||
	AccessKeyId     string `json:"AccessKeyId,omitempty"`
 | 
			
		||||
	AccessKeySecret string `json:"AccessKeySecret,omitempty"`
 | 
			
		||||
	RAMRole         string `json:"RAMRole,omitempty"`
 | 
			
		||||
	STSToken        string `json:"STSToken,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type HuaweiCloud struct {
 | 
			
		||||
	AccessKeyId     string `json:"AccessKeyId,omitempty"`
 | 
			
		||||
	Region          string `json:"Region,omitempty"`
 | 
			
		||||
	SecretAccessKey string `json:"SecretAccessKey,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type WestCN struct {
 | 
			
		||||
	Username string `json:"Username,omitempty"`
 | 
			
		||||
	Password string `json:"Password,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type RainYun struct {
 | 
			
		||||
	ApiKey string `json:"ApiKey,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Dode struct {
 | 
			
		||||
	Token string `json:"Token,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								internal/class/SafeLine/Cert.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								internal/class/SafeLine/Cert.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
			
		||||
package SafeLine
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type UpdateReq struct {
 | 
			
		||||
	Acme struct {
 | 
			
		||||
		Domains []string `json:"domains"`
 | 
			
		||||
		Email   string   `json:"email"`
 | 
			
		||||
	} `json:"acme"`
 | 
			
		||||
	Id     int `json:"id"`
 | 
			
		||||
	Manual struct {
 | 
			
		||||
		Crt string `json:"crt"`
 | 
			
		||||
		Key string `json:"key"`
 | 
			
		||||
	} `json:"manual"`
 | 
			
		||||
	Type int `json:"type"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (updateReq *UpdateReq) Create(Certificate, PrivateKey []byte, domains []string, email string, id, Type int) {
 | 
			
		||||
	updateReq.Acme.Domains = domains
 | 
			
		||||
	updateReq.Acme.Email = email
 | 
			
		||||
	updateReq.Manual.Crt = string(Certificate)
 | 
			
		||||
	updateReq.Manual.Key = string(PrivateKey)
 | 
			
		||||
	updateReq.Id = id
 | 
			
		||||
	updateReq.Type = Type
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (updateReq *UpdateReq) Marshal() []byte {
 | 
			
		||||
	data, _ := json.Marshal(updateReq)
 | 
			
		||||
	return data
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type UpdateResp struct {
 | 
			
		||||
	Data int         `json:"data"`
 | 
			
		||||
	Err  interface{} `json:"err"`
 | 
			
		||||
	Msg  string      `json:"msg"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (updateResp *UpdateResp) Unmarshal(data []byte) {
 | 
			
		||||
	_ = json.Unmarshal(data, &updateResp)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										29
									
								
								internal/class/SafeLine/CheckMethod.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								internal/class/SafeLine/CheckMethod.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,29 @@
 | 
			
		||||
package SafeLine
 | 
			
		||||
 | 
			
		||||
import "SafeLine-Acme/internal/app/logger"
 | 
			
		||||
 | 
			
		||||
func (safeLine *Object) CheckFile() bool {
 | 
			
		||||
	var flag = true
 | 
			
		||||
	if safeLine.Host == "" {
 | 
			
		||||
		logger.Warning.Printf("未设置 %s服务器主机%s: 请检查配置文件中的 %sServer.Host%s 参数", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset)
 | 
			
		||||
		flag = false
 | 
			
		||||
	}
 | 
			
		||||
	if safeLine.ApiToken == "" {
 | 
			
		||||
		logger.Warning.Printf("未设置 %sSafeLine API Token%s : 请检查配置文件中的 %sServer.ApiToken%s 参数", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset)
 | 
			
		||||
		flag = false
 | 
			
		||||
	}
 | 
			
		||||
	return flag
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (safeLine *Object) CheckCommand() bool {
 | 
			
		||||
	var flag = true
 | 
			
		||||
	if safeLine.Host == "" {
 | 
			
		||||
		logger.Warning.Printf("未设置 %s服务器主机%s: 请检查命令中的 %s-h%s 参数", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset)
 | 
			
		||||
		flag = false
 | 
			
		||||
	}
 | 
			
		||||
	if safeLine.ApiToken == "" {
 | 
			
		||||
		logger.Warning.Printf("未设置 %sSafeLine API Token%s : 请检查命令中的 %s-t%s 参数", logger.Cyan, logger.Reset, logger.Yellow, logger.Reset)
 | 
			
		||||
		flag = false
 | 
			
		||||
	}
 | 
			
		||||
	return flag
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										52
									
								
								internal/class/SafeLine/Method.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								internal/class/SafeLine/Method.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,52 @@
 | 
			
		||||
package SafeLine
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"SafeLine-Acme/internal/app/logger"
 | 
			
		||||
	"SafeLine-Acme/pkg/utils"
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"io"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"os"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (safeLine *Object) GetCertNodes() []Nodes {
 | 
			
		||||
	header := http.Header{
 | 
			
		||||
		"X-SLCE-API-TOKEN": []string{safeLine.ApiToken},
 | 
			
		||||
	}
 | 
			
		||||
	resp, err := utils.Request("GET", safeLine.SSLCertUrl(), nil, header)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logger.Error.Printf("请求接口 %s/api/open/cert%s 时发生错误: %s%s%s", logger.Cyan, logger.Reset, logger.Red, err, logger.Reset)
 | 
			
		||||
		os.Exit(0)
 | 
			
		||||
	}
 | 
			
		||||
	defer resp.Body.Close()
 | 
			
		||||
	data, _ := io.ReadAll(resp.Body)
 | 
			
		||||
	var listResp ListResp
 | 
			
		||||
	listResp.Unmarshal(data)
 | 
			
		||||
	return listResp.Data.Nodes
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (safeLine *Object) UpdateCert(email string, Certificate, PrivateKey []byte, cert Nodes) ([]string, []string) {
 | 
			
		||||
 | 
			
		||||
	header := http.Header{
 | 
			
		||||
		"X-SLCE-API-TOKEN": []string{safeLine.ApiToken},
 | 
			
		||||
		"Content-Type":     []string{"application/json"},
 | 
			
		||||
	}
 | 
			
		||||
	var updateReq UpdateReq
 | 
			
		||||
	updateReq.Create(Certificate, PrivateKey, cert.Domains, email, cert.Id, cert.Type)
 | 
			
		||||
	resp, err := utils.Request("POST", safeLine.SSLCertUrl(), bytes.NewReader(updateReq.Marshal()), header)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logger.Error.Printf("更新证书时发生错误: %s%s%s", logger.Red, err, logger.Reset)
 | 
			
		||||
		return nil, nil
 | 
			
		||||
	}
 | 
			
		||||
	defer resp.Body.Close()
 | 
			
		||||
	data, _ := io.ReadAll(resp.Body)
 | 
			
		||||
	var updateResp UpdateResp
 | 
			
		||||
	updateResp.Unmarshal(data)
 | 
			
		||||
	if updateResp.Msg != "" {
 | 
			
		||||
		logger.Error.Printf("域名 %s%s%s 证书更新失败: %s%s%s", logger.Cyan, cert.Domains, logger.Reset, logger.Red, updateResp.Msg, logger.Reset)
 | 
			
		||||
		return nil, cert.Domains
 | 
			
		||||
	}
 | 
			
		||||
	logger.Success.Printf("域名 %s%s%s 证书更新成功!", logger.Cyan, cert.Domains, logger.Reset)
 | 
			
		||||
	return cert.Domains, nil
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								internal/class/SafeLine/Object.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								internal/class/SafeLine/Object.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
package SafeLine
 | 
			
		||||
 | 
			
		||||
type Object struct {
 | 
			
		||||
	Host     string `json:"Host"`
 | 
			
		||||
	ApiToken string `json:"ApiToken"`
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										33
									
								
								internal/class/SafeLine/Other.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								internal/class/SafeLine/Other.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,33 @@
 | 
			
		||||
package SafeLine
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type ListResp struct {
 | 
			
		||||
	Data struct {
 | 
			
		||||
		Nodes []Nodes `json:"nodes"`
 | 
			
		||||
		Total int     `json:"total"`
 | 
			
		||||
	} `json:"data"`
 | 
			
		||||
	Err string `json:"err"`
 | 
			
		||||
	Msg string `json:"msg"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Nodes struct {
 | 
			
		||||
	Id            int       `json:"id"`
 | 
			
		||||
	Domains       []string  `json:"domains"`
 | 
			
		||||
	Issuer        string    `json:"issuer"`
 | 
			
		||||
	SelfSignature bool      `json:"self_signature"`
 | 
			
		||||
	Trusted       bool      `json:"trusted"`
 | 
			
		||||
	Revoked       bool      `json:"revoked"`
 | 
			
		||||
	Expired       bool      `json:"expired"`
 | 
			
		||||
	Type          int       `json:"type"`
 | 
			
		||||
	AcmeMessage   string    `json:"acme_message"`
 | 
			
		||||
	ValidBefore   time.Time `json:"valid_before"`
 | 
			
		||||
	RelatedSites  []string  `json:"related_sites"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (listResp *ListResp) Unmarshal(data []byte) {
 | 
			
		||||
	_ = json.Unmarshal(data, &listResp)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								internal/class/SafeLine/VerifyMethod.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								internal/class/SafeLine/VerifyMethod.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
			
		||||
package SafeLine
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"SafeLine-Acme/internal/app/logger"
 | 
			
		||||
	"SafeLine-Acme/pkg/utils"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"net/http"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (safeLine *Object) Verify() bool {
 | 
			
		||||
	err := safeLine.ServerVerify()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logger.Error.Printf("请求服务端时发生错误: %s%s%s", logger.Red, err.Error(), logger.Reset)
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = safeLine.AuthTokenVerify()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logger.Warning.Printf("%sSafeLine API Token%s 验证失败,请检查后重试", logger.Cyan, logger.Reset)
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	logger.Success.Printf("%sSafeLine%s 相关配置检验完成!", logger.Cyan, logger.Reset)
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (safeLine *Object) ServerVerify() error {
 | 
			
		||||
	_, err := utils.Request("GET", safeLine.Url().String(), nil, nil)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (safeLine *Object) AuthTokenVerify() error {
 | 
			
		||||
	header := http.Header{
 | 
			
		||||
		"X-SLCE-API-TOKEN": []string{safeLine.ApiToken},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	resp, err := utils.Request("GET", safeLine.AuthTokenUrl(), nil, header)
 | 
			
		||||
	if err != nil || resp.StatusCode != 200 {
 | 
			
		||||
		return errors.New("token 验证失败")
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										26
									
								
								internal/class/SafeLine/url.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								internal/class/SafeLine/url.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,26 @@
 | 
			
		||||
package SafeLine
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/url"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (safeLine *Object) Url() *url.URL {
 | 
			
		||||
	var u *url.URL
 | 
			
		||||
	u, _ = url.Parse(fmt.Sprintf("https://%s", safeLine.Host))
 | 
			
		||||
	return u
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (safeLine *Object) AuthTokenUrl() string {
 | 
			
		||||
	path := "/api/open/auth/token"
 | 
			
		||||
	u := safeLine.Url()
 | 
			
		||||
	u.Path = path
 | 
			
		||||
	return u.String()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (safeLine *Object) SSLCertUrl() string {
 | 
			
		||||
	path := "/api/open/cert"
 | 
			
		||||
	u := safeLine.Url()
 | 
			
		||||
	u.Path = path
 | 
			
		||||
	return u.String()
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user