Some checks are pending
Security Checks / security (push) Waiting to run
统一 frontend、backend、test、test-log 和 out 目录,更新构建、部署及测试入口;纳入配置管理兼容与首次安全引导修复;排除本机配置、密钥和测试产物。
142 lines
3.9 KiB
Go
142 lines
3.9 KiB
Go
package catalog
|
|
|
|
import (
|
|
"errors"
|
|
"runtime"
|
|
"sort"
|
|
"strings"
|
|
)
|
|
|
|
var (
|
|
ErrUnknownPluginID = errors.New("unknown plugin ID")
|
|
ErrInvalidPluginTarget = errors.New("invalid plugin target")
|
|
)
|
|
|
|
type Definition struct {
|
|
LogicalID string
|
|
WindowsExecutable string
|
|
UnixExecutable string
|
|
Capabilities []string
|
|
HandshakeCapabilities []string
|
|
SettingsFields []string
|
|
}
|
|
|
|
var definitions = []Definition{
|
|
{
|
|
LogicalID: "spam_block",
|
|
WindowsExecutable: "spam_block.exe",
|
|
UnixExecutable: "spam_block",
|
|
Capabilities: []string{"network"},
|
|
HandshakeCapabilities: []string{"network"},
|
|
SettingsFields: []string{"url", "timeout", "threshold"},
|
|
},
|
|
{
|
|
LogicalID: "wechat_push",
|
|
WindowsExecutable: "wechat_push.exe",
|
|
UnixExecutable: "wechat_push",
|
|
Capabilities: []string{"network"},
|
|
HandshakeCapabilities: []string{"network"},
|
|
SettingsFields: []string{"appId", "templateId", "userId", "webDomain"},
|
|
},
|
|
{
|
|
LogicalID: "telegram_push",
|
|
WindowsExecutable: "pmail_telegram_push.exe",
|
|
UnixExecutable: "pmail_telegram_push",
|
|
Capabilities: []string{"network"},
|
|
HandshakeCapabilities: []string{"network", "userSettings", "settingsHtml"},
|
|
SettingsFields: []string{"proxy", "timeout", "debug", "webDomain", "httpsEnabled"},
|
|
},
|
|
}
|
|
|
|
func Definitions() []Definition {
|
|
result := make([]Definition, len(definitions))
|
|
for index, definition := range definitions {
|
|
result[index] = cloneDefinition(definition)
|
|
}
|
|
return result
|
|
}
|
|
|
|
func Lookup(logicalID string) (Definition, bool) {
|
|
for _, definition := range definitions {
|
|
if definition.LogicalID == logicalID {
|
|
return cloneDefinition(definition), true
|
|
}
|
|
}
|
|
return Definition{}, false
|
|
}
|
|
|
|
func ExecutableName(logicalID, goos string) (string, error) {
|
|
definition, ok := Lookup(logicalID)
|
|
if !ok {
|
|
return "", ErrUnknownPluginID
|
|
}
|
|
if goos == "windows" {
|
|
return definition.WindowsExecutable, nil
|
|
}
|
|
if goos == "linux" || goos == "darwin" {
|
|
return definition.UnixExecutable, nil
|
|
}
|
|
return "", ErrInvalidPluginTarget
|
|
}
|
|
|
|
func CurrentExecutableName(logicalID string) (string, error) {
|
|
return ExecutableName(logicalID, runtime.GOOS)
|
|
}
|
|
|
|
func EnabledDefinitions(values []string, goos string) ([]Definition, error) {
|
|
enabled := make(map[string]struct{}, len(values))
|
|
for _, value := range values {
|
|
logicalID, err := LogicalIDFromValue(value, goos)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if _, exists := enabled[logicalID]; exists {
|
|
return nil, ErrInvalidPluginTarget
|
|
}
|
|
enabled[logicalID] = struct{}{}
|
|
}
|
|
result := make([]Definition, 0, len(enabled))
|
|
for _, definition := range definitions {
|
|
if _, ok := enabled[definition.LogicalID]; ok {
|
|
result = append(result, cloneDefinition(definition))
|
|
}
|
|
}
|
|
sort.Slice(result, func(left, right int) bool {
|
|
return result[left].LogicalID < result[right].LogicalID
|
|
})
|
|
return result, nil
|
|
}
|
|
|
|
func LogicalIDFromValue(value, goos string) (string, error) {
|
|
value = strings.TrimSpace(value)
|
|
if value == "" || value != strings.ToLower(value) || strings.ContainsAny(value, `/\\*?[]`) {
|
|
return "", ErrInvalidPluginTarget
|
|
}
|
|
if _, ok := Lookup(value); ok {
|
|
return value, nil
|
|
}
|
|
for _, definition := range definitions {
|
|
executable, err := ExecutableName(definition.LogicalID, goos)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
if value == executable {
|
|
return definition.LogicalID, nil
|
|
}
|
|
}
|
|
return "", ErrUnknownPluginID
|
|
}
|
|
|
|
func IsCurrentExecutable(logicalID, executable string) bool {
|
|
expected, err := CurrentExecutableName(logicalID)
|
|
return err == nil && executable == expected
|
|
}
|
|
|
|
func cloneDefinition(source Definition) Definition {
|
|
result := source
|
|
result.Capabilities = append([]string(nil), source.Capabilities...)
|
|
result.HandshakeCapabilities = append([]string(nil), source.HandshakeCapabilities...)
|
|
result.SettingsFields = append([]string(nil), source.SettingsFields...)
|
|
return result
|
|
}
|