From 683888138fa6b60a543778ab5882c907a8de2952 Mon Sep 17 00:00:00 2001 From: halo Date: Sun, 13 Aug 2023 22:04:06 +0800 Subject: [PATCH 1/7] =?UTF-8?q?perf:=20api=E8=BF=94=E5=9B=9E=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go-client/Makefile | 3 + go-client/config.json | 92 +++++++------------------- go-client/pkg/awaken/awaken.go | 85 +++++++++++++++++------- go-client/pkg/awaken/awaken_darwin.go | 49 +++++++++----- go-client/pkg/awaken/awaken_linux.go | 36 +++++++++- go-client/pkg/awaken/awaken_unix.go | 9 ++- go-client/pkg/awaken/awaken_windows.go | 14 ++-- go-client/pkg/config/config.go | 6 +- interface/package.json | 4 +- 9 files changed, 177 insertions(+), 121 deletions(-) diff --git a/go-client/Makefile b/go-client/Makefile index 54acafb..cc08eaa 100644 --- a/go-client/Makefile +++ b/go-client/Makefile @@ -20,3 +20,6 @@ build-client: GOARCH=arm64 GOOS=linux $(CLIENTBUILD) -ldflags "$(LDFLAGS)" -o $(BUILDDIR)/linux-arm64/JumpServerClient $(CLIENTSRCFILE) GOARCH=arm64 GOOS=linux $(CLIENTBUILD) -ldflags "$(LDFLAGS)" -o $(BUILDDIR)/linux-arm64/client $(SSHCSRCFILE) + + cp -R $(BUILDDIR)/* $(BASEPATH)/../interface/bin/ + cp $(BASEPATH)/config.json $(BASEPATH)/../interface/bin/ \ No newline at end of file diff --git a/go-client/config.json b/go-client/config.json index b0777c7..d8e66a2 100644 --- a/go-client/config.json +++ b/go-client/config.json @@ -172,27 +172,11 @@ "download_url": "内置", "type": "linux", "path": "Terminal", - "arg_format": "-{protocol} {username}@{host} -P {port} -pw {value}", + "arg_format": "{protocol} {username}@{host} -p {port} -P {value}", "match_first": [], "is_internal": true, "is_default": true, "is_set": true - }, - { - "name": "securecrt", - "display_name": "SecureCRT", - "protocol": [ - "ssh" - ], - "comment": "SecureCRT是VanDyke Software所开发销售的一个SSH、Telnet客户端和虚拟终端软件。\n\n!!!手动下载安装,点击保存启用!!!", - "download_url": "https://www.vandyke.com/cgi-bin/releases.php?product=securecrt", - "type": "linux", - "path": "/Applications/SecureCRT.app/Contents/MacOS/SecureCRT", - "arg_format": "/N {name} /T /SSH2 /ACCEPTHOSTKEYS /p {port} /password {value} /L {username} {host}", - "match_first": [], - "is_internal": false, - "is_default": false, - "is_set": false } ], "remotedesktop": [ @@ -210,7 +194,7 @@ "match_first": [], "is_internal": true, "is_default": true, - "is_set": false + "is_set": true } ], "filetransfer": [ @@ -246,7 +230,12 @@ "type": "databases", "path": "/Applications/DBeaver.app/Contents/MacOS/dbeaver", "arg_format": "-con name={name}|driver={protocol}|user={username}|password={value}|database={dbname}|host={host}|port={port}|save=false|connect=true", - "match_first": [], + "match_first": [ + "oracle", + "mysql", + "postgresql", + "mariadb" + ], "is_internal": false, "is_default": false, "is_set": false @@ -272,60 +261,25 @@ "is_set": true } ], - "remotedesktop": [ { - "name": "remmina", - "display_name": "Remmina", - "protocol": [ - "rdp" - ], - "comment": "Remmina 是一个使用 GTK+ 开发的远程桌面客户端,提供了 RDP、VNC、XDMCP、SSH 等远程连接协议的支持。", - "download_url": "https://remmina.org/how-to-install-remmina/-内置", - "type": "windows", - "path": "remmina", - "arg_format": "", - "match_first": [], - "is_internal": true, - "is_default": true, - "is_set": true - }], - "filetransfer": [ + "remotedesktop": [ { - "name": "filezilla", - "display_name": "Filezilla", + "name": "remmina", + "display_name": "Remmina", "protocol": [ - "sftp" + "rdp" ], - "comment": "FileZilla Client是一款免费、开源的 FTP 客户端。它支持FTP、SFTP。", - "download_url": "https://filezilla-project.org/download.php?type=client", - "type": "linux", - "path": "", - "arg_format": "{protocol}://{username}:{value}@{host}:{port}", + "comment": "Remmina 是一个使用 GTK+ 开发的远程桌面客户端,提供了 RDP、VNC、XDMCP、SSH 等远程连接协议的支持。", + "download_url": "https://remmina.org/how-to-install-remmina/-内置", + "type": "windows", + "path": "remmina", + "arg_format": "", "match_first": [], - "is_internal": false, - "is_default": false, - "is_set": false + "is_internal": true, + "is_default": true, + "is_set": true } ], - "databases": [ - { - "name": "dbeaver", - "display_name": "DBeaver Community", - "protocol": [ - "oracle", - "mysql", - "postgresql", - "mariadb" - ], - "comment": "DBeaver Community是一个通用的数据库管理工具和SQL客户端,支持MySQL、PostgreSQL、Oracle以及其他兼容JDBC的数据库。", - "download_url": "https://dbeaver.io/download/", - "type": "databases", - "path": "", - "arg_format": "-con name={name}|driver={protocol}|user={username}|password={value}|database={dbname}|host={host}|port={port}|save=false|connect=true", - "match_first": [], - "is_internal": false, - "is_default": false, - "is_set": false - } - ] + "filetransfer": [], + "databases": [] } -} +} \ No newline at end of file diff --git a/go-client/pkg/awaken/awaken.go b/go-client/pkg/awaken/awaken.go index 1b1d947..582cc8d 100755 --- a/go-client/pkg/awaken/awaken.go +++ b/go-client/pkg/awaken/awaken.go @@ -4,6 +4,7 @@ import ( "go-client/global" "go-client/pkg/config" "io/ioutil" + "net/url" "os" "path/filepath" "regexp" @@ -25,31 +26,59 @@ type File struct { Content string `json:"content"` } -type Info struct { +type Endpoint struct { + Host string `json:"host"` + Port int `json:"port"` +} + +type Token struct { + ID string `json:"id"` + Value string `json:"value"` +} + +type Asset struct { ID string `json:"id"` + Category string `json:"category"` + Type string `json:"type"` + Name string `json:"name"` + Address string `json:"address"` + DBInfo `json:"info"` +} + +type DBInfo struct { + DBName string `json:"db_name"` + UseSsl string `json:"use_ssl"` + AllowInvalidCert string `json:"allow_invalid_cert"` +} + +type Info struct { + Version string `json:"version"` Name string `json:"name"` - Value string `json:"value"` Protocol string `json:"protocol"` - Host string `json:"host"` - Port int `json:"port"` - Username string `json:"username"` Command string `json:"command"` - DBName string `json:"dbname"` + Asset `json:"asset"` + Endpoint `json:"endpoint"` + Token `json:"token"` File `json:"file"` } -type DBCommand struct { - User string `json:"user"` - Password string `json:"password"` - Host string `json:"host"` - Port string `json:"port"` - DBName string `json:"dbname"` -} - type Rouse struct { Info } +func (r *Rouse) getUserName() string { + username := r.Token.ID + if r.Protocol == "ssh" || r.Protocol == "sftp" { + username = "JMS-" + username + } + return username +} + +func (r *Rouse) getName() string { + name, _ := url.QueryUnescape(r.Name) + return name +} + func removeCurRdpFile() { re := regexp.MustCompile(".*\\.rdp$") dir := filepath.Dir(os.Args[0]) @@ -74,8 +103,7 @@ func (r *Rouse) HandleRDP(appConfig *config.AppConfig) { } func (r *Rouse) HandleSSH(appConfig *config.AppConfig) { - currentPath := filepath.Dir(os.Args[0]) - cmd := handleSSH(r, currentPath, appConfig) + cmd := handleSSH(r, appConfig) cmd.Run() } @@ -84,16 +112,25 @@ func (r *Rouse) HandleDB(appConfig *config.AppConfig) { cmd.Run() } +func (r *Rouse) HandleCommand(appConfig *config.AppConfig) { + cmd := handleCommand(r, appConfig) + cmd.Run() +} + func (r *Rouse) Run() { protocol := r.Protocol appConfig := config.GetConf() - - switch protocol { - case "rdp": - r.HandleRDP(&appConfig) - case "ssh", "sftp": - r.HandleSSH(&appConfig) - case "mysql", "mariadb", "postgresql", "redis", "oracle", "sqlserver": - r.HandleDB(&appConfig) + if r.Command == "" { + switch protocol { + case "rdp": + r.HandleRDP(&appConfig) + case "ssh", "sftp": + r.HandleSSH(&appConfig) + case "mysql", "mariadb", "postgresql", "redis", "oracle", "sqlserver": + r.HandleDB(&appConfig) + } + } else { + r.HandleCommand(&appConfig) } + } diff --git a/go-client/pkg/awaken/awaken_darwin.go b/go-client/pkg/awaken/awaken_darwin.go index afab831..ba806c1 100755 --- a/go-client/pkg/awaken/awaken_darwin.go +++ b/go-client/pkg/awaken/awaken_darwin.go @@ -4,6 +4,7 @@ import ( "fmt" "go-client/global" "go-client/pkg/config" + "os" "os/exec" "path/filepath" "strconv" @@ -23,7 +24,7 @@ func awakenRDPCommand(filePath string) *exec.Cmd { return cmd } -func awakenSSHCommand(r *Rouse, currentPath string, cfg *config.AppConfig) *exec.Cmd { +func awakenSSHCommand(r *Rouse, cfg *config.AppConfig) *exec.Cmd { var appItem *config.AppItem var appLst []config.AppItem switch r.Protocol { @@ -43,25 +44,26 @@ func awakenSSHCommand(r *Rouse, currentPath string, cfg *config.AppConfig) *exec return nil } var cmd *exec.Cmd + connectMap := map[string]string{ + "name": r.getName(), + "protocol": r.Protocol, + "username": r.getUserName(), + "value": r.Value, + "host": r.Host, + "port": strconv.Itoa(r.Port), + } + if appItem.IsInternal { + currentPath := filepath.Dir(os.Args[0]) + commands := getCommandFromArgs(connectMap, appItem.ArgFormat) clientPath := filepath.Join(currentPath, "client") - command := fmt.Sprintf("%s %s -P %s", clientPath, r.Command, r.Value) cmd = exec.Command( - "osascript", "-s", "h", - "-e", fmt.Sprintf(`tell application "%s" to do script "%s"`, appItem.DisplayName, command), + "osascript", "-s", "h", "-e", fmt.Sprintf(`tell application "%s" to do script "%s %s"`, + appItem.DisplayName, clientPath, commands), ) } else { var appPath string appPath = appItem.Path - - connectMap := map[string]string{ - "name": r.Name, - "protocol": r.Protocol, - "username": r.Username, - "value": r.Value, - "host": r.Host, - "port": strconv.Itoa(r.Port), - } commands := getCommandFromArgs(connectMap, appItem.ArgFormat) appPath = appItem.Path cmd = exec.Command(appPath, strings.Split(commands, " ")...) @@ -82,11 +84,10 @@ func awakenDBCommand(r *Rouse, cfg *config.AppConfig) *exec.Cmd { return nil } appPath := appItem.Path - connectMap := map[string]string{ - "name": r.Name, + "name": r.getName(), "protocol": r.Protocol, - "username": r.Username, + "username": r.getUserName(), "value": r.Value, "host": r.Host, "port": strconv.Itoa(r.Port), @@ -95,3 +96,19 @@ func awakenDBCommand(r *Rouse, cfg *config.AppConfig) *exec.Cmd { commands := getCommandFromArgs(connectMap, appItem.ArgFormat) return exec.Command(appPath, strings.Split(commands, " ")...) } + +func awakenOtherCommand(r *Rouse, cfg *config.AppConfig) *exec.Cmd { + var command string + if r.Protocol == "ssh" { + currentPath := filepath.Dir(os.Args[0]) + clientPath := filepath.Join(currentPath, "client") + command = fmt.Sprintf("%s %s -P %s", clientPath, r.Command, r.Value) + } else { + command = r.Command + } + cmd := exec.Command( + "osascript", "-s", "h", + "-e", fmt.Sprintf(`tell application "%s" to do script "%s"`, "Terminal", command), + ) + return cmd +} diff --git a/go-client/pkg/awaken/awaken_linux.go b/go-client/pkg/awaken/awaken_linux.go index 7e8ad89..17963cd 100755 --- a/go-client/pkg/awaken/awaken_linux.go +++ b/go-client/pkg/awaken/awaken_linux.go @@ -4,6 +4,7 @@ import ( "fmt" "go-client/global" "go-client/pkg/config" + "os" "os/exec" "path/filepath" "strconv" @@ -23,7 +24,8 @@ func awakenRDPCommand(filePath string) *exec.Cmd { return cmd } -func awakenSSHCommand(r *Rouse, currentPath string, cfg *config.AppConfig) *exec.Cmd { +func awakenSSHCommand(r *Rouse, cfg *config.AppConfig) *exec.Cmd { + currentPath := filepath.Dir(os.Args[0]) clientPath := filepath.Join(currentPath, "client") command := fmt.Sprintf("%s %s -P %s", clientPath, r.Command, r.Value) cmd := new(exec.Cmd) @@ -60,9 +62,9 @@ func awakenDBCommand(r *Rouse, cfg *config.AppConfig) *exec.Cmd { appPath := appItem.Path connectMap := map[string]string{ - "name": r.Name, + "name": r.getName(), "protocol": r.Protocol, - "username": r.Username, + "username": r.getUserName(), "value": r.Value, "host": r.Host, "port": strconv.Itoa(r.Port), @@ -71,3 +73,31 @@ func awakenDBCommand(r *Rouse, cfg *config.AppConfig) *exec.Cmd { commands := getCommandFromArgs(connectMap, appItem.ArgFormat) return exec.Command(appPath, strings.Split(commands, " ")...) } + +func awakenOtherCommand(r *Rouse, cfg *config.AppConfig) *exec.Cmd { + var command string + if r.Protocol == "ssh" { + currentPath := filepath.Dir(os.Args[0]) + clientPath := filepath.Join(currentPath, "client") + command = fmt.Sprintf("%s %s -P %s", clientPath, r.Command, r.Value) + } else { + command = r.Command + } + cmd := new(exec.Cmd) + out, _ := exec.Command("bash", "-c", "echo $XDG_CURRENT_DESKTOP").CombinedOutput() + currentDesktop := strings.ToLower(strings.Trim(string(out), "\n")) + + switch currentDesktop { + case "gnome": + cmd = exec.Command( + "gnome-terminal", "--", "bash", "-c", + fmt.Sprintf("%s; exec bash -i", command), + ) + case "deepin": + cmd = exec.Command("deepin-terminal", "--keep-open", "-C", command) + default: + msg := fmt.Sprintf("Not yet supported %s desktop system", currentDesktop) + global.LOG.Info(msg) + } + return cmd +} diff --git a/go-client/pkg/awaken/awaken_unix.go b/go-client/pkg/awaken/awaken_unix.go index 47a894c..7c39d90 100755 --- a/go-client/pkg/awaken/awaken_unix.go +++ b/go-client/pkg/awaken/awaken_unix.go @@ -13,8 +13,8 @@ func handleRDP(r *Rouse, filePath string, cfg *config.AppConfig) *exec.Cmd { return cmd } -func handleSSH(r *Rouse, currentPath string, cfg *config.AppConfig) *exec.Cmd { - cmd := awakenSSHCommand(r, currentPath, cfg) +func handleSSH(r *Rouse, cfg *config.AppConfig) *exec.Cmd { + cmd := awakenSSHCommand(r, cfg) return cmd } @@ -22,3 +22,8 @@ func handleDB(r *Rouse, cfg *config.AppConfig) *exec.Cmd { cmd := awakenDBCommand(r, cfg) return cmd } + +func handleCommand(r *Rouse, cfg *config.AppConfig) *exec.Cmd { + cmd := awakenOtherCommand(r, cfg) + return cmd +} diff --git a/go-client/pkg/awaken/awaken_windows.go b/go-client/pkg/awaken/awaken_windows.go index 8d5df0d..959a69f 100755 --- a/go-client/pkg/awaken/awaken_windows.go +++ b/go-client/pkg/awaken/awaken_windows.go @@ -33,7 +33,7 @@ func handleRDP(r *Rouse, filePath string, cfg *config.AppConfig) *exec.Cmd { return cmd } -func handleSSH(r *Rouse, currentPath string, cfg *config.AppConfig) *exec.Cmd { +func handleSSH(r *Rouse, cfg *config.AppConfig) *exec.Cmd { var appItem *config.AppItem var appLst []config.AppItem switch r.Protocol { @@ -54,6 +54,7 @@ func handleSSH(r *Rouse, currentPath string, cfg *config.AppConfig) *exec.Cmd { } var appPath string if appItem.IsInternal { + currentPath := filepath.Dir(os.Args[0]) appPath = filepath.Join(currentPath, appItem.Path) } else { appPath = appItem.Path @@ -62,7 +63,7 @@ func handleSSH(r *Rouse, currentPath string, cfg *config.AppConfig) *exec.Cmd { connectMap := map[string]string{ "name": r.Name, "protocol": r.Protocol, - "username": r.Username, + "username": r.getUserName(), "value": r.Value, "host": r.Host, "port": strconv.Itoa(r.Port), @@ -88,7 +89,7 @@ func handleDB(r *Rouse, cfg *config.AppConfig) *exec.Cmd { connectMap := map[string]string{ "name": r.Name, "protocol": r.Protocol, - "username": r.Username, + "username": r.getUserName(), "value": r.Value, "host": r.Host, "port": strconv.Itoa(r.Port), @@ -101,7 +102,7 @@ func handleDB(r *Rouse, cfg *config.AppConfig) *exec.Cmd { ss["host"] = r.Host ss["port"] = strconv.Itoa(r.Port) ss["name"] = r.Name - ss["auth"] = r.Username + "@" + r.Value + ss["auth"] = r.Token.ID + "@" + r.Value ss["ssh_agent_path"] = "" ss["ssh_password"] = "" ss["ssh_private_key_path"] = "" @@ -125,3 +126,8 @@ func handleDB(r *Rouse, cfg *config.AppConfig) *exec.Cmd { commands := getCommandFromArgs(connectMap, appItem.ArgFormat) return exec.Command(appPath, strings.Split(commands, " ")...) } + +func handleCommand(r *Rouse, cfg *config.AppConfig) *exec.Cmd { + cmd := exec.Command(r.Command) + return cmd +} diff --git a/go-client/pkg/config/config.go b/go-client/pkg/config/config.go index 9ca2c9d..16b5b95 100644 --- a/go-client/pkg/config/config.go +++ b/go-client/pkg/config/config.go @@ -70,8 +70,10 @@ func GetConf() AppConfig { var GlobalConfig *AppConfig func getDefaultConfig() AppConfig { - //filePath := filepath.Join(filepath.Dir(os.Args[0]), "config.json") - filePath := filepath.Join("/Users/halo/golang/clients/interface/bin/config.json") + filePath := filepath.Join(filepath.Dir(os.Args[0]), "../config.json") + if os.Getenv("DEBUG") == "True" { + filePath = filepath.Join("../interface/bin/config.json") + } jsonFile, err := os.Open(filePath) if err != nil { global.LOG.Error(err.Error()) diff --git a/interface/package.json b/interface/package.json index 5b4f7f0..d780fce 100644 --- a/interface/package.json +++ b/interface/package.json @@ -7,7 +7,9 @@ "scripts": { "serve": "vue-cli-service electron:serve", "lint": "vue-cli-service lint", - "electron:build": "vue-cli-service electron:build", + "build:mac": "vue-cli-service electron:build --macos", + "build:linux": "vue-cli-service electron:build --linux", + "build:win": "vue-cli-service electron:build --windows", "electron:serve": "vue-cli-service electron:serve", "postinstall": "electron-builder install-app-deps", "postuninstall": "electron-builder install-app-deps" From 5977cd5ba3c7bbe30c4d330afd59390417c20356 Mon Sep 17 00:00:00 2001 From: halo Date: Mon, 14 Aug 2023 13:56:23 +0800 Subject: [PATCH 2/7] =?UTF-8?q?perf:=20=E6=89=93=E5=8C=85=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go-client/pkg/awaken/awaken_darwin.go | 2 +- interface/src/background.js | 12 ++++++------ interface/src/renderer/components/ListTable.vue | 4 ++-- interface/src/renderer/layouts/Main.vue | 2 +- interface/src/renderer/pages/About.vue | 2 +- interface/vue.config.js | 5 ++--- 6 files changed, 13 insertions(+), 14 deletions(-) diff --git a/go-client/pkg/awaken/awaken_darwin.go b/go-client/pkg/awaken/awaken_darwin.go index ba806c1..0d48c17 100755 --- a/go-client/pkg/awaken/awaken_darwin.go +++ b/go-client/pkg/awaken/awaken_darwin.go @@ -58,7 +58,7 @@ func awakenSSHCommand(r *Rouse, cfg *config.AppConfig) *exec.Cmd { commands := getCommandFromArgs(connectMap, appItem.ArgFormat) clientPath := filepath.Join(currentPath, "client") cmd = exec.Command( - "osascript", "-s", "h", "-e", fmt.Sprintf(`tell application "%s" to do script "%s %s"`, + "osascript", "-s", "h", "-e", fmt.Sprintf(`tell application "%s" to do script "%s %s" activate`, appItem.DisplayName, clientPath, commands), ) } else { diff --git a/interface/src/background.js b/interface/src/background.js index 54306ec..9f5b73c 100644 --- a/interface/src/background.js +++ b/interface/src/background.js @@ -160,12 +160,12 @@ const hideWindow = () => { } } -app.on('second-instance', (event, commandLine, workingDirectory) => { - let commands = commandLine.slice(); - // commandLine 是一个数组, 其中最后一个数组元素为我们唤醒的链接 - let urlStr = commands.pop(); - handleOpenFromUrl(urlStr) -}) +// app.on('second-instance', (event, commandLine, workingDirectory) => { +// let commands = commandLine.slice(); +// // commandLine 是一个数组, 其中最后一个数组元素为我们唤醒的链接 +// let urlStr = commands.pop(); +// handleOpenFromUrl(urlStr) +// }) let STORE_PATH diff --git a/interface/src/renderer/components/ListTable.vue b/interface/src/renderer/components/ListTable.vue index c324892..40bdbdd 100644 --- a/interface/src/renderer/components/ListTable.vue +++ b/interface/src/renderer/components/ListTable.vue @@ -78,7 +78,7 @@ export default { } .app-info { - padding: 5px 3px; + padding: 10px 10px; height: 100%; width: 100%; display: flex; @@ -93,7 +93,7 @@ export default { margin-left: 10px; color: #eee; display: inline-block; - width: calc(100% - 60px); + width: calc(100% - 70px); .title { font-size: 16px; diff --git a/interface/src/renderer/layouts/Main.vue b/interface/src/renderer/layouts/Main.vue index 6d0c0f3..b2042f4 100644 --- a/interface/src/renderer/layouts/Main.vue +++ b/interface/src/renderer/layouts/Main.vue @@ -39,7 +39,7 @@ - + 关于我们 diff --git a/interface/src/renderer/pages/About.vue b/interface/src/renderer/pages/About.vue index 51df6fc..94f39d9 100644 --- a/interface/src/renderer/pages/About.vue +++ b/interface/src/renderer/pages/About.vue @@ -2,7 +2,7 @@

本地客户端工具

- 作者:Fit2Cloud - Halo + 作者:FIT2CLOUD 飞致云 - Halo
diff --git a/interface/vue.config.js b/interface/vue.config.js index 1b50f8f..957cb25 100644 --- a/interface/vue.config.js +++ b/interface/vue.config.js @@ -18,7 +18,7 @@ module.exports = { nodeIntegration: true, customFileProtocol: './', builderOptions: { - productName: 'JumpServer本地客户端工具', + productName: 'JumpServerClient', appId: 'com.jumpserver.client', asar: false, extraResources: [ @@ -65,8 +65,7 @@ module.exports = { target: [{ target: 'nsis', arch: [ - 'x64', - 'ia32' + 'x64' ] }] }, From c231113cc4bccb3659417b01d7e41e3d81f9d251 Mon Sep 17 00:00:00 2001 From: halo Date: Mon, 14 Aug 2023 14:27:52 +0800 Subject: [PATCH 3/7] =?UTF-8?q?perf:=20rdp=E4=B8=AD=E6=96=87=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=90=8D=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go-client/pkg/awaken/awaken.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/go-client/pkg/awaken/awaken.go b/go-client/pkg/awaken/awaken.go index 582cc8d..d63b3e9 100755 --- a/go-client/pkg/awaken/awaken.go +++ b/go-client/pkg/awaken/awaken.go @@ -92,7 +92,8 @@ func removeCurRdpFile() { func (r *Rouse) HandleRDP(appConfig *config.AppConfig) { removeCurRdpFile() - filePath := filepath.Join(filepath.Dir(os.Args[0]), r.File.Name+".rdp") + fileName, _ := url.QueryUnescape(r.File.Name) + filePath := filepath.Join(filepath.Dir(os.Args[0]), fileName+".rdp") err := ioutil.WriteFile(filePath, []byte(r.Content), os.ModePerm) if err != nil { global.LOG.Error(err.Error()) From 208cb7240e99f3bd00f34c9771cdb8a4d7a9cbc3 Mon Sep 17 00:00:00 2001 From: halo Date: Mon, 14 Aug 2023 15:52:05 +0800 Subject: [PATCH 4/7] =?UTF-8?q?perf:=20=E6=95=B0=E6=8D=AE=E5=BA=93?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=BB=88=E7=AB=AF=E5=BA=94=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go-client/config.json | 30 ++++++++++++++++--- go-client/pkg/awaken/awaken_darwin.go | 27 +++++++++++++++-- .../src/renderer/components/ListTable.vue | 25 +++++++++------- 3 files changed, 65 insertions(+), 17 deletions(-) diff --git a/go-client/config.json b/go-client/config.json index d8e66a2..6f951dc 100644 --- a/go-client/config.json +++ b/go-client/config.json @@ -216,6 +216,32 @@ } ], "databases": [ + { + "name": "terminal", + "display_name": "Terminal", + "protocol": [ + "oracle", + "mysql", + "postgresql", + "mariadb", + "redis" + ], + "comment": "Terminal是MacOS操作系统上的虚拟终端应用软件,位于“实用工具”文件夹内。", + "download_url": "内置", + "type": "linux", + "path": "Terminal", + "arg_format": "", + "match_first": [ + "oracle", + "mysql", + "postgresql", + "mariadb", + "redis" + ], + "is_internal": true, + "is_default": false, + "is_set": true + }, { "name": "dbeaver", "display_name": "DBeaver Community", @@ -231,10 +257,6 @@ "path": "/Applications/DBeaver.app/Contents/MacOS/dbeaver", "arg_format": "-con name={name}|driver={protocol}|user={username}|password={value}|database={dbname}|host={host}|port={port}|save=false|connect=true", "match_first": [ - "oracle", - "mysql", - "postgresql", - "mariadb" ], "is_internal": false, "is_default": false, diff --git a/go-client/pkg/awaken/awaken_darwin.go b/go-client/pkg/awaken/awaken_darwin.go index 0d48c17..8b9b194 100755 --- a/go-client/pkg/awaken/awaken_darwin.go +++ b/go-client/pkg/awaken/awaken_darwin.go @@ -93,8 +93,31 @@ func awakenDBCommand(r *Rouse, cfg *config.AppConfig) *exec.Cmd { "port": strconv.Itoa(r.Port), "dbname": r.DBName, } - commands := getCommandFromArgs(connectMap, appItem.ArgFormat) - return exec.Command(appPath, strings.Split(commands, " ")...) + if appItem.IsInternal { + var argFormat string + switch r.Protocol { + case "redis": + argFormat = "redis-cli -h {host} -p {port} -a {username}@{value}" + case "oracle": + argFormat = "sqlplus {username}/{value}@{host}:{port}/{dbname}" + case "postgresql": + argFormat = "psql user={username} password={value} host={host} dbname={dbname} port={port}" + case "mysql", "mariadb": + argFormat = "mysql -u{username} -p{value} -h {host} -P {port} {dbname}" + } + currentPath := filepath.Dir(os.Args[0]) + commands := getCommandFromArgs(connectMap, argFormat) + clientPath := filepath.Join(currentPath, "client") + cmd := exec.Command( + "osascript", "-s", "h", "-e", fmt.Sprintf(`tell application "%s" to do script "%s %s" activate`, + appItem.DisplayName, clientPath, commands), + ) + return cmd + } else { + appPath = appItem.Path + commands := getCommandFromArgs(connectMap, appItem.ArgFormat) + return exec.Command(appPath, strings.Split(commands, " ")...) + } } func awakenOtherCommand(r *Rouse, cfg *config.AppConfig) *exec.Cmd { diff --git a/interface/src/renderer/components/ListTable.vue b/interface/src/renderer/components/ListTable.vue index 40bdbdd..0692a87 100644 --- a/interface/src/renderer/components/ListTable.vue +++ b/interface/src/renderer/components/ListTable.vue @@ -7,7 +7,7 @@
{{ d.display_name }}
{{ d.comment }}
-
+
{{ is_set_string(d.is_set) }} @@ -111,18 +111,21 @@ export default { line-height: 24px; } - .is-setted { - font-size: 12px; - color: #5cb87a; - } + .prop{ + .is-setted { + font-size: 12px; + color: #5cb87a; + } - .not-setted { - font-size: 12px; - color: #e6a23c; - } + .not-setted { + font-size: 12px; + color: #e6a23c; + } - .match_first { - color: #5cb87a; + .match_first { + font-size: 11px; + color: #5cb87a; + } } } } From 0987c7cd48b4d7380e8cf5cfc4032578c5456c44 Mon Sep 17 00:00:00 2001 From: halo Date: Mon, 14 Aug 2023 16:04:04 +0800 Subject: [PATCH 5/7] =?UTF-8?q?perf:=20=E6=95=B0=E6=8D=AE=E5=BA=93?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=BB=88=E7=AB=AF=E5=BA=94=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go-client/pkg/awaken/awaken_darwin.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/go-client/pkg/awaken/awaken_darwin.go b/go-client/pkg/awaken/awaken_darwin.go index 8b9b194..facde44 100755 --- a/go-client/pkg/awaken/awaken_darwin.go +++ b/go-client/pkg/awaken/awaken_darwin.go @@ -103,14 +103,12 @@ func awakenDBCommand(r *Rouse, cfg *config.AppConfig) *exec.Cmd { case "postgresql": argFormat = "psql user={username} password={value} host={host} dbname={dbname} port={port}" case "mysql", "mariadb": - argFormat = "mysql -u{username} -p{value} -h {host} -P {port} {dbname}" + argFormat = "mysql -u {username} -p{value} -h {host} -P {port} {dbname}" } - currentPath := filepath.Dir(os.Args[0]) commands := getCommandFromArgs(connectMap, argFormat) - clientPath := filepath.Join(currentPath, "client") cmd := exec.Command( - "osascript", "-s", "h", "-e", fmt.Sprintf(`tell application "%s" to do script "%s %s" activate`, - appItem.DisplayName, clientPath, commands), + "osascript", "-s", "h", "-e", fmt.Sprintf(`tell application "%s" to do script "%s" activate`, + appItem.DisplayName, commands), ) return cmd } else { From 3036cd34d48d5f23d90ba58160fc9d37e626fac0 Mon Sep 17 00:00:00 2001 From: halo Date: Wed, 16 Aug 2023 12:04:13 +0800 Subject: [PATCH 6/7] =?UTF-8?q?perf:=20linux=20=E5=AE=89=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go-client/config.json | 67 +++++++++---- go-client/pkg/awaken/awaken_linux.go | 133 +++++++++++++++++-------- interface/build/linux/after-install.sh | 31 ++++++ interface/package.json | 2 +- interface/src/background.js | 8 +- interface/vue.config.js | 7 +- 6 files changed, 176 insertions(+), 72 deletions(-) create mode 100755 interface/build/linux/after-install.sh diff --git a/go-client/config.json b/go-client/config.json index 6f951dc..9b5364c 100644 --- a/go-client/config.json +++ b/go-client/config.json @@ -2,6 +2,23 @@ "filename": "Jumpserve Clients Config", "windows": { "terminal": [ + { + "name": "putty", + "display_name": "PuTTY", + "protocol": [ + "ssh", + "telnet" + ], + "comment": "PuTTY是一个Telnet、SSH、rlogin纯TCP以及串行阜连线软件。", + "download_url": "内置", + "type": "linux", + "path": "putty.exe", + "arg_format": "-{protocol} {username}@{host} -P {port} -pw {value}", + "match_first": [], + "is_internal": true, + "is_default": true, + "is_set": true + }, { "name": "xshell", "display_name": "XShell", @@ -35,23 +52,6 @@ "is_internal": false, "is_default": false, "is_set": false - }, - { - "name": "putty", - "display_name": "PuTTY", - "protocol": [ - "ssh", - "telnet" - ], - "comment": "PuTTY是一个Telnet、SSH、rlogin纯TCP以及串行阜连线软件。", - "download_url": "内置", - "type": "linux", - "path": "putty.exe", - "arg_format": "-{protocol} {username}@{host} -P {port} -pw {value}", - "match_first": [], - "is_internal": true, - "is_default": true, - "is_set": true } ], "remotedesktop": [ @@ -272,11 +272,11 @@ "protocol": [ "ssh" ], - "comment": "Terminal是MacOS操作系统上的虚拟终端应用软件,位于“实用工具”文件夹内。", + "comment": "Terminal是Linux操作系统上的虚拟终端应用软件。", "download_url": "内置", "type": "linux", "path": "Terminal", - "arg_format": "-{protocol} {username}@{host} -P {port} -pw {value}", + "arg_format": "{protocol} {username}@{host} -p {port} -P {value}", "match_first": [], "is_internal": true, "is_default": true, @@ -302,6 +302,33 @@ } ], "filetransfer": [], - "databases": [] + "databases": [ + { + "name": "terminal", + "display_name": "Terminal", + "protocol": [ + "oracle", + "mysql", + "postgresql", + "mariadb", + "redis" + ], + "comment": "Terminal是Linux操作系统上的虚拟终端应用软件。", + "download_url": "内置", + "type": "linux", + "path": "Terminal", + "arg_format": "", + "match_first": [ + "oracle", + "mysql", + "postgresql", + "mariadb", + "redis" + ], + "is_internal": true, + "is_default": false, + "is_set": true + } + ] } } \ No newline at end of file diff --git a/go-client/pkg/awaken/awaken_linux.go b/go-client/pkg/awaken/awaken_linux.go index 17963cd..bbd47ee 100755 --- a/go-client/pkg/awaken/awaken_linux.go +++ b/go-client/pkg/awaken/awaken_linux.go @@ -25,31 +25,66 @@ func awakenRDPCommand(filePath string) *exec.Cmd { } func awakenSSHCommand(r *Rouse, cfg *config.AppConfig) *exec.Cmd { - currentPath := filepath.Dir(os.Args[0]) - clientPath := filepath.Join(currentPath, "client") - command := fmt.Sprintf("%s %s -P %s", clientPath, r.Command, r.Value) - cmd := new(exec.Cmd) - out, _ := exec.Command("bash", "-c", "echo $XDG_CURRENT_DESKTOP").CombinedOutput() - currentDesktop := strings.ToLower(strings.Trim(string(out), "\n")) + var appItem *config.AppItem + var appLst []config.AppItem + switch r.Protocol { + case "ssh": + appLst = cfg.Linux.Terminal + case "sftp": + appLst = cfg.Linux.FileTransfer + } + + for _, app := range appLst { + if app.IsActive() && app.IsSupportProtocol(r.Protocol) { + appItem = &app + break + } + } + if appItem == nil { + return nil + } + var cmd *exec.Cmd + connectMap := map[string]string{ + "name": r.getName(), + "protocol": r.Protocol, + "username": r.getUserName(), + "value": r.Value, + "host": r.Host, + "port": strconv.Itoa(r.Port), + } - switch currentDesktop { - case "gnome": - cmd = exec.Command( - "gnome-terminal", "--", "bash", "-c", - fmt.Sprintf("%s; exec bash -i", command), - ) - case "deepin": - cmd = exec.Command("deepin-terminal", "--keep-open", "-C", command) - default: - msg := fmt.Sprintf("Not yet supported %s desktop system", currentDesktop) - global.LOG.Info(msg) + if appItem.IsInternal { + currentPath := filepath.Dir(os.Args[0]) + commands := getCommandFromArgs(connectMap, appItem.ArgFormat) + clientPath := filepath.Join(currentPath, "client") + out, _ := exec.Command("bash", "-c", "echo $XDG_CURRENT_DESKTOP").CombinedOutput() + currentDesktop := strings.ToLower(strings.Trim(string(out), "\n")) + + switch currentDesktop { + case "gnome": + cmd = exec.Command( + "gnome-terminal", "--", "bash", "-c", + fmt.Sprintf("%s %s; exec bash -i", clientPath, commands), + ) + case "deepin": + cmd = exec.Command("deepin-terminal", "--keep-open", "-C", fmt.Sprintf("%s %s", clientPath, commands)) + default: + msg := fmt.Sprintf("Not yet supported %s desktop system", currentDesktop) + global.LOG.Info(msg) + } + } else { + var appPath string + appPath = appItem.Path + commands := getCommandFromArgs(connectMap, appItem.ArgFormat) + appPath = appItem.Path + cmd = exec.Command(appPath, strings.Split(commands, " ")...) } return cmd } func awakenDBCommand(r *Rouse, cfg *config.AppConfig) *exec.Cmd { var appItem *config.AppItem - appLst := cfg.Windows.Databases + appLst := cfg.Linux.Databases for _, app := range appLst { if app.IsSet && app.IsMatchProtocol(r.Protocol) { appItem = &app @@ -59,8 +94,8 @@ func awakenDBCommand(r *Rouse, cfg *config.AppConfig) *exec.Cmd { if appItem == nil { return nil } + var cmd *exec.Cmd appPath := appItem.Path - connectMap := map[string]string{ "name": r.getName(), "protocol": r.Protocol, @@ -70,34 +105,44 @@ func awakenDBCommand(r *Rouse, cfg *config.AppConfig) *exec.Cmd { "port": strconv.Itoa(r.Port), "dbname": r.DBName, } - commands := getCommandFromArgs(connectMap, appItem.ArgFormat) - return exec.Command(appPath, strings.Split(commands, " ")...) -} + if appItem.IsInternal { + var argFormat string + switch r.Protocol { + case "redis": + argFormat = "redis-cli -h {host} -p {port} -a {username}@{value}" + case "oracle": + argFormat = "sqlplus {username}/{value}@{host}:{port}/{dbname}" + case "postgresql": + argFormat = "psql user={username} password={value} host={host} dbname={dbname} port={port}" + case "mysql", "mariadb": + argFormat = "mysql -u {username} -p{value} -h {host} -P {port} {dbname}" + } + commands := getCommandFromArgs(connectMap, argFormat) -func awakenOtherCommand(r *Rouse, cfg *config.AppConfig) *exec.Cmd { - var command string - if r.Protocol == "ssh" { - currentPath := filepath.Dir(os.Args[0]) - clientPath := filepath.Join(currentPath, "client") - command = fmt.Sprintf("%s %s -P %s", clientPath, r.Command, r.Value) + out, _ := exec.Command("bash", "-c", "echo $XDG_CURRENT_DESKTOP").CombinedOutput() + currentDesktop := strings.ToLower(strings.Trim(string(out), "\n")) + + switch currentDesktop { + case "gnome": + cmd = exec.Command( + "gnome-terminal", "--", "bash", "-c", + fmt.Sprintf("%s; exec bash -i", commands), + ) + case "deepin": + cmd = exec.Command("deepin-terminal", "--keep-open", "-C", commands) + default: + msg := fmt.Sprintf("Not yet supported %s desktop system", currentDesktop) + global.LOG.Info(msg) + } + return cmd } else { - command = r.Command + appPath = appItem.Path + commands := getCommandFromArgs(connectMap, appItem.ArgFormat) + return exec.Command(appPath, strings.Split(commands, " ")...) } - cmd := new(exec.Cmd) - out, _ := exec.Command("bash", "-c", "echo $XDG_CURRENT_DESKTOP").CombinedOutput() - currentDesktop := strings.ToLower(strings.Trim(string(out), "\n")) +} - switch currentDesktop { - case "gnome": - cmd = exec.Command( - "gnome-terminal", "--", "bash", "-c", - fmt.Sprintf("%s; exec bash -i", command), - ) - case "deepin": - cmd = exec.Command("deepin-terminal", "--keep-open", "-C", command) - default: - msg := fmt.Sprintf("Not yet supported %s desktop system", currentDesktop) - global.LOG.Info(msg) - } +func awakenOtherCommand(r *Rouse, cfg *config.AppConfig) *exec.Cmd { + cmd := new(exec.Cmd) return cmd } diff --git a/interface/build/linux/after-install.sh b/interface/build/linux/after-install.sh new file mode 100755 index 0000000..bed255f --- /dev/null +++ b/interface/build/linux/after-install.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# apt install remmina gnome-terminal deepin-terminal -y +set -e +INSTALLDIR='/opt/JumpServerClient' + +# SUID chrome-sandbox for Electron 5+ +chmod 4755 '/opt/${sanitizedProductName}/chrome-sandbox' || true + +chmod -R 777 '/opt/${sanitizedProductName}/resources/bin' + +ARCH=$(uname -m) +if [[ $ARCH == 'aarch64' ]];then + ARCH='arm64' +else + ARCH='amd64' +fi + +echo "[Desktop Entry] +Name=jms +Exec=$INSTALLDIR/resources/bin/linux-$ARCH/JumpServerClient %u +Type=Application +Terminal=false +MimeType=x-scheme-handler/jms;" > /usr/share/applications/jms.desktop + +update-desktop-database /usr/share/applications + +xdg-mime default /usr/share/applications/jms.desktop x-scheme-handler/jms + +update-mime-database /usr/share/mime + +exit 0 \ No newline at end of file diff --git a/interface/package.json b/interface/package.json index d780fce..467598c 100644 --- a/interface/package.json +++ b/interface/package.json @@ -1,5 +1,5 @@ { - "name": "interface", + "name": "jumpserver-client", "author": "Fit2Cloud Technology Co., Ltd.; ", "version": "v2.0.0", "homepage": "https://jumpserver.org", diff --git a/interface/src/background.js b/interface/src/background.js index 9f5b73c..482608d 100644 --- a/interface/src/background.js +++ b/interface/src/background.js @@ -110,12 +110,14 @@ if (isDevelopment) { } -if (process.defaultApp) { +if (process.platform === "darwin") { + if (process.defaultApp) { if (process.argv.length >= 2) { - app.setAsDefaultProtocolClient('jms', process.execPath, [path.resolve(process.argv[1])]) + app.setAsDefaultProtocolClient('jms', process.execPath, [path.resolve(process.argv[1])]) } -} else { + } else { app.setAsDefaultProtocolClient('jms') + } } const handleOpenFromUrl = (url) => { diff --git a/interface/vue.config.js b/interface/vue.config.js index 957cb25..791a235 100644 --- a/interface/vue.config.js +++ b/interface/vue.config.js @@ -39,6 +39,9 @@ module.exports = { } ] }, + deb: { + afterInstall:"build/linux/after-install.sh", + }, mac: { icon: 'build/icons/icon.icns', extendInfo: { @@ -77,10 +80,6 @@ module.exports = { icon: 'build/icons/', // eslint-disable-next-line no-template-curly-in-string artifactName: 'JumpServer-Clients-Installer-${os}-${version}-${arch}.deb', - protocols: { - name: "Jms", - schemes: ["jms"] - }, target: [{ target: 'deb', arch: [ From 0ed7afcfe9a2a966dd3cbd10acaca0f414cd6ee1 Mon Sep 17 00:00:00 2001 From: halo Date: Wed, 16 Aug 2023 13:53:15 +0800 Subject: [PATCH 7/7] =?UTF-8?q?fix:=20ubuntu=E6=A1=8C=E9=9D=A2=E7=8E=AF?= =?UTF-8?q?=E5=A2=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go-client/pkg/awaken/awaken_linux.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go-client/pkg/awaken/awaken_linux.go b/go-client/pkg/awaken/awaken_linux.go index bbd47ee..24e8e1e 100755 --- a/go-client/pkg/awaken/awaken_linux.go +++ b/go-client/pkg/awaken/awaken_linux.go @@ -61,7 +61,7 @@ func awakenSSHCommand(r *Rouse, cfg *config.AppConfig) *exec.Cmd { currentDesktop := strings.ToLower(strings.Trim(string(out), "\n")) switch currentDesktop { - case "gnome": + case "gnome", "ubuntu:gnome": cmd = exec.Command( "gnome-terminal", "--", "bash", "-c", fmt.Sprintf("%s %s; exec bash -i", clientPath, commands), @@ -123,7 +123,7 @@ func awakenDBCommand(r *Rouse, cfg *config.AppConfig) *exec.Cmd { currentDesktop := strings.ToLower(strings.Trim(string(out), "\n")) switch currentDesktop { - case "gnome": + case "gnome", "ubuntu:gnome": cmd = exec.Command( "gnome-terminal", "--", "bash", "-c", fmt.Sprintf("%s; exec bash -i", commands),