完成资产附加属性功能
This commit is contained in:
parent
25c3c6b929
commit
7599c09191
2
main.go
2
main.go
@ -22,7 +22,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
const Version = "v0.1.2"
|
||||
const Version = "v0.2.0"
|
||||
|
||||
func main() {
|
||||
log.Fatal(Run())
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/pkg/sftp"
|
||||
"github.com/sirupsen/logrus"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
@ -362,8 +363,16 @@ func SessionLsEndpoint(c echo.Context) error {
|
||||
return errors.New("获取sftp客户端失败")
|
||||
}
|
||||
|
||||
if tun.Subject.NextTerminal == nil {
|
||||
nextTerminal, err := CreateNextTerminalBySession(session)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tun.Subject.NextTerminal = nextTerminal
|
||||
}
|
||||
|
||||
if tun.Subject.NextTerminal.SftpClient == nil {
|
||||
sftpClient, err := CreateSftpClient(session)
|
||||
sftpClient, err := sftp.NewClient(tun.Subject.NextTerminal.SshClient)
|
||||
if err != nil {
|
||||
logrus.Errorf("创建sftp客户端失败:%v", err.Error())
|
||||
return err
|
||||
|
@ -4,9 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/pkg/sftp"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/crypto/ssh"
|
||||
"net/http"
|
||||
"next-terminal/pkg/global"
|
||||
"next-terminal/pkg/guacd"
|
||||
@ -97,6 +95,7 @@ func SSHEndpoint(c echo.Context) (err error) {
|
||||
|
||||
tun := global.Tun{
|
||||
Protocol: session.Protocol,
|
||||
Mode: session.Mode,
|
||||
WebSocket: ws,
|
||||
}
|
||||
|
||||
@ -242,18 +241,6 @@ func WriteMessage(ws *websocket.Conn, msg Message) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func CreateSshClientBySession(session model.Session) (sshClient *ssh.Client, err error) {
|
||||
|
||||
var (
|
||||
username = session.Username
|
||||
password = session.Password
|
||||
privateKey = session.PrivateKey
|
||||
passphrase = session.Passphrase
|
||||
)
|
||||
|
||||
return term.NewSshClient(session.IP, session.Port, username, password, privateKey, passphrase)
|
||||
}
|
||||
|
||||
func WriteByteMessage(ws *websocket.Conn, p []byte) {
|
||||
err := ws.WriteMessage(websocket.TextMessage, p)
|
||||
if err != nil {
|
||||
@ -261,11 +248,14 @@ func WriteByteMessage(ws *websocket.Conn, p []byte) {
|
||||
}
|
||||
}
|
||||
|
||||
func CreateSftpClient(session model.Session) (sftpClient *sftp.Client, err error) {
|
||||
sshClient, err := CreateSshClientBySession(session)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return sftp.NewClient(sshClient)
|
||||
func CreateNextTerminalBySession(session model.Session) (*term.NextTerminal, error) {
|
||||
var (
|
||||
username = session.Username
|
||||
password = session.Password
|
||||
privateKey = session.PrivateKey
|
||||
passphrase = session.Passphrase
|
||||
ip = session.IP
|
||||
port = session.Port
|
||||
)
|
||||
return term.NewNextTerminal(ip, port, username, password, privateKey, passphrase, 10, 10, "")
|
||||
}
|
||||
|
@ -154,8 +154,9 @@ func TunEndpoint(c echo.Context) error {
|
||||
|
||||
tun := global.Tun{
|
||||
Protocol: session.Protocol,
|
||||
Tunnel: tunnel,
|
||||
Mode: session.Mode,
|
||||
WebSocket: ws,
|
||||
Tunnel: tunnel,
|
||||
}
|
||||
|
||||
if len(session.ConnectionId) == 0 {
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
|
||||
type Tun struct {
|
||||
Protocol string
|
||||
Mode string
|
||||
WebSocket *websocket.Conn
|
||||
Tunnel *guacd.Tunnel
|
||||
NextTerminal *term.NextTerminal
|
||||
@ -25,7 +26,7 @@ func (r *Tun) Close(code int, reason string) {
|
||||
|
||||
ws := r.WebSocket
|
||||
if ws != nil {
|
||||
if r.Protocol == "rdp" || r.Protocol == "vnc" {
|
||||
if r.Mode == "guacd" {
|
||||
err := guacd.NewInstruction("error", reason, strconv.Itoa(code))
|
||||
_ = ws.WriteMessage(websocket.TextMessage, []byte(err.String()))
|
||||
disconnect := guacd.NewInstruction("disconnect")
|
||||
|
@ -92,6 +92,8 @@ func FindAssetAttrMapByAssetId(assetId string) (map[string]interface{}, error) {
|
||||
parameterNames = RDPParameterNames
|
||||
case "vnc":
|
||||
parameterNames = VNCParameterNames
|
||||
case "telnet":
|
||||
parameterNames = TelnetParameterNames
|
||||
}
|
||||
propertiesMap := FindAllPropertiesMap()
|
||||
var attributeMap = make(map[string]interface{})
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "next-terminal",
|
||||
"version": "0.1.2",
|
||||
"version": "0.2.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^4.3.0",
|
||||
|
@ -575,23 +575,45 @@ class Access extends Component {
|
||||
</Affix>
|
||||
</Draggable>
|
||||
|
||||
<Draggable>
|
||||
<Affix style={{position: 'absolute', top: 100, right: 100}}>
|
||||
<Button icon={<AppstoreTwoTone/>} onClick={() => {
|
||||
this.setState({
|
||||
fileSystemVisible: true,
|
||||
});
|
||||
}}/>
|
||||
</Affix>
|
||||
</Draggable>
|
||||
{
|
||||
this.state.protocol === 'rdp' ?
|
||||
<>
|
||||
<Draggable>
|
||||
<Affix style={{position: 'absolute', top: 100, right: 100}}>
|
||||
<Button icon={<AppstoreTwoTone/>} onClick={() => {
|
||||
this.setState({
|
||||
fileSystemVisible: true,
|
||||
});
|
||||
}}/>
|
||||
</Affix>
|
||||
</Draggable>
|
||||
|
||||
<Draggable>
|
||||
<Affix style={{position: 'absolute', top: 100, right: 150}}>
|
||||
<Dropdown overlay={menu} trigger={['click']} placement="bottomLeft">
|
||||
<Button icon={<DesktopOutlined/>}/>
|
||||
</Dropdown>
|
||||
</Affix>
|
||||
</Draggable>
|
||||
</> : undefined
|
||||
}
|
||||
|
||||
{
|
||||
this.state.protocol === 'ssh' ?
|
||||
<>
|
||||
<Draggable>
|
||||
<Affix style={{position: 'absolute', top: 100, right: 100}}>
|
||||
<Button icon={<AppstoreTwoTone/>} onClick={() => {
|
||||
this.setState({
|
||||
fileSystemVisible: true,
|
||||
});
|
||||
}}/>
|
||||
</Affix>
|
||||
</Draggable>
|
||||
|
||||
</> : undefined
|
||||
}
|
||||
|
||||
<Draggable>
|
||||
<Affix style={{position: 'absolute', top: 100, right: 150}}>
|
||||
<Dropdown overlay={menu} trigger={['click']} placement="bottomLeft">
|
||||
<Button icon={<DesktopOutlined/>}/>
|
||||
</Dropdown>
|
||||
</Affix>
|
||||
</Draggable>
|
||||
|
||||
<Drawer
|
||||
title={'会话详情'}
|
||||
|
@ -285,128 +285,6 @@ Windows需要对远程应用程序的名称使用特殊的符号。
|
||||
<Input type='text' placeholder="remote app的命令行参数"/>
|
||||
</Form.Item>
|
||||
</Panel>
|
||||
<Panel header={<Text strong>性能</Text>} key="性能">
|
||||
<Form.Item
|
||||
{...RDPFormItemLayout}
|
||||
name="enable-wallpaper"
|
||||
label="启用桌面墙纸"
|
||||
valuePropName="checked"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Switch checkedChildren="开启" unCheckedChildren="关闭"/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
{...RDPFormItemLayout}
|
||||
name="enable-theming"
|
||||
label="启用桌面主题"
|
||||
valuePropName="checked"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Switch checkedChildren="开启" unCheckedChildren="关闭"/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
{...RDPFormItemLayout}
|
||||
name="enable-font-smoothing"
|
||||
label="启用字体平滑(ClearType)"
|
||||
valuePropName="checked"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Switch checkedChildren="开启" unCheckedChildren="关闭"/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
{...RDPFormItemLayout}
|
||||
name="enable-full-window-drag"
|
||||
label="启用全窗口拖拽"
|
||||
valuePropName="checked"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Switch checkedChildren="开启" unCheckedChildren="关闭"/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
{...RDPFormItemLayout}
|
||||
name="enable-desktop-composition"
|
||||
label="启用桌面合成效果(Aero)"
|
||||
valuePropName="checked"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Switch checkedChildren="开启" unCheckedChildren="关闭"/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
{...RDPFormItemLayout}
|
||||
name="enable-menu-animations"
|
||||
label="启用菜单动画"
|
||||
valuePropName="checked"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Switch checkedChildren="开启" unCheckedChildren="关闭"/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
{...RDPFormItemLayout}
|
||||
name="disable-bitmap-caching"
|
||||
label="禁用位图缓存"
|
||||
valuePropName="checked"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Switch checkedChildren="开启" unCheckedChildren="关闭"/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
{...RDPFormItemLayout}
|
||||
name="disable-offscreen-caching"
|
||||
label="禁用离屏缓存"
|
||||
valuePropName="checked"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Switch checkedChildren="开启" unCheckedChildren="关闭"/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
{...RDPFormItemLayout}
|
||||
name="disable-glyph-caching"
|
||||
label="禁用字形缓存"
|
||||
valuePropName="checked"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Switch checkedChildren="开启" unCheckedChildren="关闭"/>
|
||||
</Form.Item>
|
||||
</Panel>
|
||||
</> : undefined
|
||||
}
|
||||
|
||||
@ -503,14 +381,6 @@ Windows需要对远程应用程序的名称使用特殊的符号。
|
||||
<Option value="remote">远程</Option>
|
||||
</Select>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="swap-red-blue"
|
||||
label="交换红蓝成分"
|
||||
valuePropName="checked"
|
||||
>
|
||||
<Switch checkedChildren="开启" unCheckedChildren="关闭"/>
|
||||
</Form.Item>
|
||||
</Panel>
|
||||
<Panel header={<Text strong>VNC中继</Text>} key="VNC中继">
|
||||
<Form.Item label={<Tooltip
|
||||
|
@ -41,7 +41,6 @@ class Setting extends Component {
|
||||
rdpSettingFormRef = React.createRef();
|
||||
sshSettingFormRef = React.createRef();
|
||||
vncSettingFormRef = React.createRef();
|
||||
telnetSettingFormRef = React.createRef();
|
||||
otherSettingFormRef = React.createRef();
|
||||
|
||||
componentDidMount() {
|
||||
@ -72,6 +71,9 @@ class Setting extends Component {
|
||||
if (!properties.hasOwnProperty(key)) {
|
||||
continue;
|
||||
}
|
||||
if (properties[key] === '-') {
|
||||
properties[key] = '';
|
||||
}
|
||||
if (key.startsWith('enable') || key.startsWith("disable" || key === 'swap-red-blue')) {
|
||||
properties[key] = properties[key].bool();
|
||||
}
|
||||
@ -93,10 +95,6 @@ class Setting extends Component {
|
||||
this.vncSettingFormRef.current.setFieldsValue(properties)
|
||||
}
|
||||
|
||||
if (this.telnetSettingFormRef.current) {
|
||||
this.telnetSettingFormRef.current.setFieldsValue(properties)
|
||||
}
|
||||
|
||||
if (this.otherSettingFormRef.current) {
|
||||
this.otherSettingFormRef.current.setFieldsValue(properties)
|
||||
}
|
||||
@ -317,11 +315,11 @@ class Setting extends Component {
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</TabPane>
|
||||
<TabPane tab="SSH配置" key="ssh">
|
||||
<TabPane tab="SSH/TELNET配置" key="ssh">
|
||||
<Form ref={this.sshSettingFormRef} name="ssh" onFinish={this.changeProperties}
|
||||
layout="vertical">
|
||||
|
||||
<Title level={3}>SSH配置</Title>
|
||||
<Title level={3}>SSH/TELNET配置</Title>
|
||||
|
||||
<Form.Item
|
||||
{...formItemLayout}
|
||||
@ -474,97 +472,6 @@ class Setting extends Component {
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</TabPane>
|
||||
<TabPane tab="TELNET配置" key="telnet">
|
||||
<Form ref={this.telnetSettingFormRef} name="telnet" onFinish={this.changeProperties}
|
||||
layout="vertical">
|
||||
|
||||
<Title level={3}>TELNET配置</Title>
|
||||
|
||||
<Form.Item
|
||||
{...formItemLayout}
|
||||
name="color-scheme"
|
||||
label="配色方案"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: '配色方案',
|
||||
},
|
||||
]}
|
||||
initialValue="gray-black"
|
||||
>
|
||||
<Select style={{width: 120}} onChange={null}>
|
||||
<Option value="gray-black">黑底灰字</Option>
|
||||
<Option value="green-black">黑底绿字</Option>
|
||||
<Option value="white-black">黑底白字</Option>
|
||||
<Option value="black-white">白底黑字</Option>
|
||||
</Select>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
{...formItemLayout}
|
||||
name="font-name"
|
||||
label="字体名称"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: '字体名称',
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input type='text' placeholder="请输入字体名称"/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
{...formItemLayout}
|
||||
name="font-size"
|
||||
label="字体大小"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: '字体大小',
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input type='number' placeholder="请输入字体大小"/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="backspace"
|
||||
label="退格键映射"
|
||||
{...formItemLayout}
|
||||
initialValue=""
|
||||
>
|
||||
<Select onChange={null}>
|
||||
<Option value="">默认</Option>
|
||||
<Option value="127">删除键(Ctrl-?)</Option>
|
||||
<Option value="8">退格键(Ctrl-H)</Option>
|
||||
</Select>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="terminal-type"
|
||||
label="终端类型"
|
||||
{...formItemLayout}
|
||||
initialValue=""
|
||||
>
|
||||
<Select onChange={null}>
|
||||
<Option value="">默认</Option>
|
||||
<Option value="ansi">ansi</Option>
|
||||
<Option value="linux">linux</Option>
|
||||
<Option value="vt100">vt100</Option>
|
||||
<Option value="vt220">vt220</Option>
|
||||
<Option value="xterm">xterm</Option>
|
||||
<Option value="xterm-256color">xterm-256color</Option>
|
||||
</Select>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item {...formTailLayout}>
|
||||
<Button type="primary" htmlType="submit">
|
||||
更新
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</TabPane>
|
||||
<TabPane tab="其他配置" key="other">
|
||||
<Title level={3}>Guacd 服务配置</Title>
|
||||
<Form ref={this.otherSettingFormRef} name="password" onFinish={this.changeProperties}
|
||||
|
Loading…
Reference in New Issue
Block a user