From 86ef89ff21d68bc0000a20a8ce8e1aad8468998a Mon Sep 17 00:00:00 2001 From: dushixiang <798148596@qq.com> Date: Sun, 31 Jan 2021 20:20:40 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E4=BF=AE=E6=94=B9=E6=8E=A5=E5=85=A5?= =?UTF-8?q?=E8=B5=84=E4=BA=A7=E6=97=B6=E7=AA=97=E5=8F=A3=E6=A0=87=E9=A2=98?= =?UTF-8?q?=E4=B8=BA=E8=B5=84=E4=BA=A7=E5=90=8D=E7=A7=B0=20-=20=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E7=94=A8=E6=88=B7=E5=B1=9E=E6=80=A7=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/api/session.go | 2 +- pkg/api/ssh.go | 78 +++++++++---------- .../{asset-group.go => asset-attribute.go} | 0 pkg/model/user-attribute.go | 27 +++++++ web/src/components/access/Access.js | 2 +- web/src/components/access/AccessSSH.js | 26 ++++++- 6 files changed, 89 insertions(+), 46 deletions(-) rename pkg/model/{asset-group.go => asset-attribute.go} (100%) create mode 100644 pkg/model/user-attribute.go diff --git a/pkg/api/session.go b/pkg/api/session.go index f5d9311..d12422b 100644 --- a/pkg/api/session.go +++ b/pkg/api/session.go @@ -364,7 +364,7 @@ func SessionLsEndpoint(c echo.Context) error { } if tun.Subject.SftpClient == nil { - sftpClient, err := CreateSftpClient(session.AssetId) + sftpClient, err := CreateSftpClient(session) if err != nil { logrus.Errorf("创建sftp客户端失败:%v", err.Error()) return err diff --git a/pkg/api/ssh.go b/pkg/api/ssh.go index 0d71f65..e6f8d45 100644 --- a/pkg/api/ssh.go +++ b/pkg/api/ssh.go @@ -3,7 +3,6 @@ package api import ( "bytes" "encoding/json" - "errors" "fmt" "github.com/gorilla/websocket" "github.com/labstack/echo/v4" @@ -73,10 +72,20 @@ func SSHEndpoint(c echo.Context) error { return err } - assetId := c.QueryParam("assetId") + sessionId := c.QueryParam("sessionId") width, _ := strconv.Atoi(c.QueryParam("width")) height, _ := strconv.Atoi(c.QueryParam("height")) + aSession, err := model.FindSessionById(sessionId) + if err != nil { + msg := Message{ + Type: Closed, + Content: "get session error." + err.Error(), + } + _ = WriteMessage(ws, msg) + return err + } + user, _ := GetCurrentAccount(c) if model.TypeUser == user.Type { // 检测是否有访问权限 @@ -85,12 +94,16 @@ func SSHEndpoint(c echo.Context) error { return err } - if !utils.Contains(assetIds, assetId) { - return errors.New("您没有权限访问此资产") + if !utils.Contains(assetIds, aSession.AssetId) { + msg := Message{ + Type: Closed, + Content: "您没有权限访问此资产", + } + return WriteMessage(ws, msg) } } - sshClient, err := CreateSshClient(assetId) + sshClient, err := CreateSshClientBySession(aSession) if err != nil { logrus.Errorf("创建SSH客户端失败:%v", err.Error()) msg := Message{ @@ -142,7 +155,7 @@ func SSHEndpoint(c echo.Context) error { } _ = WriteMessage(ws, msg) - recorder, err := NewRecorder("./" + assetId + ".cast") + recorder, err := NewRecorder("./" + sessionId + ".cast") if err != nil { return err } @@ -179,13 +192,12 @@ func SSHEndpoint(c echo.Context) error { } if n > 0 { s := string(p) + // 录屏 + _ = recorder.WriteData(s) msg := Message{ Type: Data, Content: s, } - // 录屏 - _ = recorder.WriteData(s) - message, err := json.Marshal(msg) if err != nil { logrus.Warnf("生成Json失败 %v", err) @@ -231,6 +243,11 @@ func SSHEndpoint(c echo.Context) error { _, err = stdinPipe.Write([]byte(msg.Content)) if err != nil { logrus.Debugf("SSH会话写入失败: %v", err) + msg := Message{ + Type: Closed, + Content: "the remote connection is closed.", + } + _ = WriteMessage(ws, msg) } } @@ -247,36 +264,17 @@ func WriteMessage(ws *websocket.Conn, msg Message) error { return err } -func CreateSshClient(assetId string) (*ssh.Client, error) { - asset, err := model.FindAssetById(assetId) - if err != nil { - return nil, err - } - +func CreateSshClientBySession(session model.Session) (sshClient *ssh.Client, err error) { var ( - accountType = asset.AccountType - username = asset.Username - password = asset.Password - privateKey = asset.PrivateKey - passphrase = asset.Passphrase + username = session.Username + password = session.Password + privateKey = session.PrivateKey + passphrase = session.Passphrase ) var authMethod ssh.AuthMethod - if accountType == "credential" { - - credential, err := model.FindCredentialById(asset.CredentialId) - if err != nil { - return nil, err - } - accountType = credential.Type - username = credential.Username - password = credential.Password - privateKey = credential.PrivateKey - passphrase = credential.Passphrase - } - - if username == "-" { - username = "" + if username == "-" || username == "" { + username = "root" } if password == "-" { password = "" @@ -288,7 +286,7 @@ func CreateSshClient(assetId string) (*ssh.Client, error) { passphrase = "" } - if accountType == model.PrivateKey { + if privateKey != "" { var key ssh.Signer if len(passphrase) > 0 { key, err = ssh.ParsePrivateKeyWithPassphrase([]byte(privateKey), []byte(passphrase)) @@ -313,9 +311,9 @@ func CreateSshClient(assetId string) (*ssh.Client, error) { HostKeyCallback: ssh.InsecureIgnoreHostKey(), } - addr := fmt.Sprintf("%s:%d", asset.IP, asset.Port) + addr := fmt.Sprintf("%s:%d", session.IP, session.Port) - sshClient, err := ssh.Dial("tcp", addr, config) + sshClient, err = ssh.Dial("tcp", addr, config) if err != nil { return nil, err } @@ -329,8 +327,8 @@ func WriteByteMessage(ws *websocket.Conn, p []byte) { } } -func CreateSftpClient(assetId string) (sftpClient *sftp.Client, err error) { - sshClient, err := CreateSshClient(assetId) +func CreateSftpClient(session model.Session) (sftpClient *sftp.Client, err error) { + sshClient, err := CreateSshClientBySession(session) if err != nil { return nil, err } diff --git a/pkg/model/asset-group.go b/pkg/model/asset-attribute.go similarity index 100% rename from pkg/model/asset-group.go rename to pkg/model/asset-attribute.go diff --git a/pkg/model/user-attribute.go b/pkg/model/user-attribute.go new file mode 100644 index 0000000..ba48254 --- /dev/null +++ b/pkg/model/user-attribute.go @@ -0,0 +1,27 @@ +package model + +import "next-terminal/pkg/global" + +const ( + FontSize = "font-size" +) + +type UserAttribute struct { + Id string `gorm:"index" json:"id"` + UserId string `gorm:"index" json:"userId"` + Name string `gorm:"index" json:"name"` + Value string `json:"value"` +} + +func (r *UserAttribute) TableName() string { + return "user_attributes" +} + +func CreateUserAttribute(o *UserAttribute) error { + return global.DB.Create(o).Error +} + +func FindUserAttributeByUserId(userId string) (o []UserAttribute, err error) { + err = global.DB.Where("user_id = ?", userId).Find(&o).Error + return o, err +} diff --git a/web/src/components/access/Access.js b/web/src/components/access/Access.js index 7412c49..c34e7a8 100644 --- a/web/src/components/access/Access.js +++ b/web/src/components/access/Access.js @@ -436,7 +436,7 @@ class Access extends Component { this.showMessage(result['message']); return null; } - document.title = result['data']['ip'] + ':' + result['data']['port']; + document.title = result['data']['name']; return result['data']['id']; } diff --git a/web/src/components/access/AccessSSH.js b/web/src/components/access/AccessSSH.js index 559c726..cc516c8 100644 --- a/web/src/components/access/AccessSSH.js +++ b/web/src/components/access/AccessSSH.js @@ -4,9 +4,10 @@ import {Terminal} from "xterm"; import qs from "qs"; import {wsServer} from "../../common/constants"; import "./Console.css" -import {getToken} from "../../utils/utils"; +import {getToken, isEmpty} from "../../utils/utils"; import {FitAddon} from 'xterm-addon-fit'; import "./Access.css" +import request from "../../common/request"; class AccessSSH extends Component { @@ -18,15 +19,20 @@ class AccessSSH extends Component { fitAddon: undefined }; - componentDidMount() { + componentDidMount = async () => { let urlParams = new URLSearchParams(this.props.location.search); let assetId = urlParams.get('assetId'); + let sessionId = await this.createSession(assetId); + if (isEmpty(sessionId)) { + return; + } + let params = { 'width': this.state.width, 'height': this.state.height, - 'assetId': assetId + 'sessionId': sessionId }; let paramStr = qs.stringify(params); @@ -104,6 +110,7 @@ class AccessSSH extends Component { let msg = JSON.parse(e.data); switch (msg['type']) { case 'connected': + term.clear(); console.log(msg['content']) this.onWindowResize(); break; @@ -135,6 +142,16 @@ class AccessSSH extends Component { } } + async createSession(assetsId) { + let result = await request.post(`/sessions?assetId=${assetsId}`); + if (result['code'] !== 1) { + this.showMessage(result['message']); + return null; + } + document.title = result['data']['name']; + return result['data']['id']; + } + terminalSize() { return { cols: Math.floor(this.state.width / 7.5), @@ -169,8 +186,9 @@ class AccessSSH extends Component {
);