merge: 合并代码
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# 项目信息
|
||||
framework:
|
||||
name: "CN EMS"
|
||||
version: "2.2403.1"
|
||||
version: "2.2404.6"
|
||||
|
||||
# 应用服务配置
|
||||
server:
|
||||
@@ -68,6 +68,8 @@ upload:
|
||||
# 软件包
|
||||
- ".deb"
|
||||
- ".rpm"
|
||||
# 验证文件
|
||||
- ".ini"
|
||||
|
||||
# cors 跨域
|
||||
cors:
|
||||
|
||||
@@ -26,6 +26,9 @@ const (
|
||||
|
||||
// 软件包
|
||||
SOFTWARE = "software"
|
||||
|
||||
// 授权文件
|
||||
LICENSE = "license"
|
||||
)
|
||||
|
||||
// 子路径类型映射
|
||||
@@ -38,4 +41,5 @@ var UploadSubpath = map[string]string{
|
||||
DOWNLOAD: "下载",
|
||||
CHUNK: "切片",
|
||||
SOFTWARE: "软件包",
|
||||
LICENSE: "授权文件",
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package i18n
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
systemService "be.ems/src/modules/system/service"
|
||||
)
|
||||
@@ -70,6 +71,26 @@ func UpdateKeyValue(language, key, value string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// TFindKeyPrefix 翻译值查找键 值前缀匹配
|
||||
func TFindKeyPrefix(language, keyPrefix, value string) string {
|
||||
key := value
|
||||
if value == "" {
|
||||
return key
|
||||
}
|
||||
arr, ok := localeMap[language]
|
||||
if !ok || len(arr) == 0 {
|
||||
arr = LoadLocaleData(language)
|
||||
}
|
||||
|
||||
for _, v := range arr {
|
||||
if strings.HasPrefix(v.Key, keyPrefix) && strings.HasPrefix(v.Value, value) {
|
||||
key = v.Key
|
||||
break
|
||||
}
|
||||
}
|
||||
return key
|
||||
}
|
||||
|
||||
// TKey 翻译键
|
||||
func TKey(language, key string) string {
|
||||
value := key
|
||||
|
||||
@@ -17,6 +17,8 @@ const (
|
||||
YYYYMMDDHHMMSS = "20060102150405"
|
||||
// 年-月-日 时:分:秒 列如:2022-12-30 01:01:59
|
||||
YYYY_MM_DD_HH_MM_SS = "2006-01-02 15:04:05"
|
||||
// 年-月-日T时:分:秒Z时区 列如:2022-12-30T01:01:59+08:00
|
||||
YYYY_MM_DDTHH_MM_SSZ = time.RFC3339
|
||||
)
|
||||
|
||||
// 格式时间字符串
|
||||
|
||||
@@ -60,9 +60,12 @@ func uploadWhiteList() []string {
|
||||
// fileName 原始文件名称含后缀,如:logo.png
|
||||
func generateFileName(fileName string) string {
|
||||
fileExt := filepath.Ext(fileName)
|
||||
// 替换掉后缀和特殊字符保留文件名
|
||||
// 去除后缀
|
||||
newFileName := regular.Replace(fileName, fileExt, "")
|
||||
newFileName = regular.Replace(newFileName, `[<>:"\\|?*]+`, "")
|
||||
// 去除非法字符
|
||||
newFileName = regular.Replace(newFileName, `[\\/:*?"<>|]`, "")
|
||||
// 去除空格
|
||||
newFileName = regular.Replace(newFileName, `\s`, "_")
|
||||
newFileName = strings.TrimSpace(newFileName)
|
||||
return fmt.Sprintf("%s_%s%s", newFileName, generate.Code(6), fileExt)
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ func ValidMobile(mobile string) bool {
|
||||
if mobile == "" {
|
||||
return false
|
||||
}
|
||||
pattern := `^1[3|4|5|6|7|8|9][0-9]\d{8}$`
|
||||
pattern := `^.{3,}$` // `^1[3|4|5|6|7|8|9][0-9]\d{8}$`
|
||||
match, err := regexp.MatchString(pattern, mobile)
|
||||
if err != nil {
|
||||
return false
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/config"
|
||||
"be.ems/src/framework/logger"
|
||||
@@ -16,9 +17,9 @@ func FileSCPLocalToNe(neIp, localPath, nePath string) error {
|
||||
// scp /path/to/local/file.txt user@remote-server:/path/to/remote/directory/
|
||||
neDir := fmt.Sprintf("%s@%s:%s", usernameNe, neIp, nePath)
|
||||
cmd := exec.Command("scp", "-r", localPath, neDir)
|
||||
_, err := cmd.CombinedOutput()
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
logger.Errorf("FileSCPLocalToNe %s", err.Error())
|
||||
logger.Errorf("FileSCPLocalToNe %s => %s", output, err.Error())
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -31,13 +32,23 @@ func FileSCPNeToLocal(neIp, nePath, localPath string) error {
|
||||
logger.Errorf("FileSCPNeToLocal MkdirAll err %v", err)
|
||||
return err
|
||||
}
|
||||
// 如果目标文件已经存在,先将目标文件重命名
|
||||
if info, err := os.Stat(localPath); err == nil && !info.IsDir() {
|
||||
ext := filepath.Ext(localPath)
|
||||
name := localPath[0 : len(localPath)-len(ext)]
|
||||
newName := fmt.Sprintf("%s-%s%s", name, time.Now().Format("20060102_150405"), ext)
|
||||
err := os.Rename(localPath, newName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
usernameNe := config.Get("ne.user").(string)
|
||||
// scp user@remote-server:/path/to/remote/directory/ /path/to/local/file.txt
|
||||
neDir := fmt.Sprintf("%s@%s:%s", usernameNe, neIp, nePath)
|
||||
cmd := exec.Command("scp", "-r", neDir, localPath)
|
||||
_, err := cmd.CombinedOutput()
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
logger.Errorf("FileSCPNeToLocal %s", err.Error())
|
||||
logger.Errorf("FileSCPNeToLocal %s => %s", output, err.Error())
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/cmd"
|
||||
gossh "golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
@@ -96,20 +97,11 @@ func (c *ConnSSH) Close() {
|
||||
func (c *ConnSSH) NewClientByLocalPrivate() (*ConnSSH, error) {
|
||||
c.Port = 22
|
||||
c.AuthMode = "1"
|
||||
usr, err := user.Current()
|
||||
privateKey, err := c.CurrentUserRsaKey(false)
|
||||
if err != nil {
|
||||
logger.Errorf("NewClientByLocal get current user => %s", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 读取用户默认的私钥文件
|
||||
keyPath := fmt.Sprintf("%s/.ssh/id_rsa", usr.HomeDir)
|
||||
key, err := os.ReadFile(keyPath)
|
||||
if err != nil {
|
||||
logger.Errorf("NewClientByLocal [%s] read private key => %s", usr.Username, err.Error())
|
||||
return nil, err
|
||||
}
|
||||
c.PrivateKey = string(key)
|
||||
c.PrivateKey = privateKey
|
||||
return c.NewClient()
|
||||
}
|
||||
|
||||
@@ -134,7 +126,55 @@ func (c *ConnSSH) RunCMD(cmd string) (string, error) {
|
||||
return c.LastResult, err
|
||||
}
|
||||
|
||||
// NewClient 创建SSH客户端会话对象
|
||||
// SendToAuthorizedKeys 发送当前用户私钥到远程服务器进行授权密钥
|
||||
func (c *ConnSSH) SendToAuthorizedKeys() error {
|
||||
publicKey, err := c.CurrentUserRsaKey(true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
authorizedKeysEntry := fmt.Sprintln(strings.TrimSpace(publicKey))
|
||||
cmdStr := "echo '" + authorizedKeysEntry + "' >> ~/.ssh/authorized_keys"
|
||||
_, err = c.RunCMD(cmdStr)
|
||||
if err != nil {
|
||||
logger.Errorf("SendAuthorizedKeys echo err %s", err.Error())
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CurrentUserRsaKey 当前用户OMC使用的RSA私钥
|
||||
// 默认读取私钥
|
||||
// ssh-keygen -t rsa -P "" -f ~/.ssh/id_rsa
|
||||
// ssh-keygen -y -f ~/.ssh/id_rsa > ~/.ssh/id_rsa.pub
|
||||
func (c *ConnSSH) CurrentUserRsaKey(publicKey bool) (string, error) {
|
||||
usr, err := user.Current()
|
||||
if err != nil {
|
||||
logger.Errorf("CurrentUserRsaKey get => %s", err.Error())
|
||||
return "", err
|
||||
}
|
||||
|
||||
// 是否存在私钥并创建
|
||||
keyPath := fmt.Sprintf("%s/.ssh/id_rsa", usr.HomeDir)
|
||||
if _, err := os.Stat(keyPath); err != nil {
|
||||
_, err2 := cmd.ExecWithCheck("ssh-keygen", "-t", "rsa", "-P", "", "-f", keyPath)
|
||||
if err2 != nil {
|
||||
logger.Errorf("CurrentUserPrivateKey ssh-keygen [%s] rsa => %s", usr.Username, err2.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// 读取用户默认的文件
|
||||
if publicKey {
|
||||
keyPath = keyPath + ".pub"
|
||||
}
|
||||
key, err := os.ReadFile(keyPath)
|
||||
if err != nil {
|
||||
logger.Errorf("CurrentUserRsaKey [%s] read => %s", usr.Username, err.Error())
|
||||
return "", fmt.Errorf("read file %s fail", keyPath)
|
||||
}
|
||||
return string(key), nil
|
||||
}
|
||||
|
||||
// NewClientSession 创建SSH客户端会话对象
|
||||
func (c *ConnSSH) NewClientSession(cols, rows int) (*SSHClientSession, error) {
|
||||
sshSession, err := c.Client.NewSession()
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user