mirror of https://github.com/tp4a/teleport
配置远程账号时可以不设置密码,让用户在进行远程连接时手动输入。
parent
fef0e95846
commit
5c286811c9
|
@ -21,7 +21,7 @@
|
|||
"name": "securecrt",
|
||||
"display": "SecureCRT",
|
||||
"app": "/Applications/SecureCRT.app/Contents/MacOS/SecureCRT",
|
||||
"cmdline": "/T /N \"TP#ssh://{real_ip}\" /SSH2 /L {user_name} /PASSWORD **** {host_ip}:{host_port}",
|
||||
"cmdline": "/T /N \"TP#ssh://{real_ip}\" /SSH2 /L {user_name} {password:/PASSWORD ****} {host_ip}:{host_port}",
|
||||
"desc": []
|
||||
},
|
||||
{
|
||||
|
@ -41,14 +41,14 @@
|
|||
"name": "securefx",
|
||||
"display": "SecureFX",
|
||||
"app": "/Applications/SecureFX.app/Contents/MacOS/SecureFX",
|
||||
"cmdline": "sftp://{user_name}:****@{host_ip}:{host_port}",
|
||||
"cmdline": "sftp://{user_name}{password::****}@{host_ip}:{host_port}",
|
||||
"desc": []
|
||||
},
|
||||
{
|
||||
"name": "filezilla",
|
||||
"display": "FileZilla",
|
||||
"app": "/Applications/FileZilla.app/Contents/MacOS/filezilla",
|
||||
"cmdline": "sftp://{user_name}:****@{host_ip}:{host_port}",
|
||||
"cmdline": "{interactive:-l ask} sftp://{user_name}{password::****}@{host_ip}:{host_port}",
|
||||
"desc": []
|
||||
},
|
||||
{
|
||||
|
|
|
@ -6,28 +6,28 @@
|
|||
"name": "putty",
|
||||
"display": "PuTTY(内置)",
|
||||
"app": "{assist_tools_path}\\putty\\putty.exe",
|
||||
"cmdline": "-ssh -pw **** -P {host_port} -l {user_name} {host_ip}",
|
||||
"cmdline": "-ssh {password:-pw ****} -P {host_port} -l {user_name} {host_ip}",
|
||||
"desc": []
|
||||
},
|
||||
{
|
||||
"name": "crt",
|
||||
"display": "SecureCRT",
|
||||
"app": "",
|
||||
"cmdline": "/T /N \"TP#ssh://{real_ip}\" /SSH2 /P {host_port} /PASSWORD **** {user_name}@{host_ip}",
|
||||
"cmdline": "/T /N \"TP#ssh://{real_ip}\" /SSH2 /P {host_port} {password:/PASSWORD ****} {user_name}@{host_ip}",
|
||||
"desc": []
|
||||
},
|
||||
{
|
||||
"name": "xshell",
|
||||
"display": "Xshell",
|
||||
"app": "",
|
||||
"cmdline": "-newtab \"TP#ssh://{real_ip}\" -url ssh://{user_name}:****@{host_ip}:{host_port}",
|
||||
"cmdline": "-newtab \"TP#ssh://{real_ip}\" -url ssh://{user_name}{password::****}@{host_ip}:{host_port}",
|
||||
"desc": []
|
||||
},
|
||||
{
|
||||
"name": "mobaxterm",
|
||||
"display": "MobaXterm",
|
||||
"app": "",
|
||||
"cmdline": "-newtab \"sshpass -p**** ssh {user_name}@{host_ip} -p {host_port}\"",
|
||||
"cmdline": "-newtab \"sshpass {password:-p****} ssh {user_name}@{host_ip} -p {host_port}\"",
|
||||
"desc": []
|
||||
},
|
||||
{
|
||||
|
@ -45,7 +45,7 @@
|
|||
"name": "winscp",
|
||||
"display": "WinSCP(内置)",
|
||||
"app": "{assist_tools_path}\\winscp\\winscp.exe",
|
||||
"cmdline": "/sessionname=\"TP#{real_ip}\" {user_name}:****@{host_ip}:{host_port}",
|
||||
"cmdline": "/sessionname=\"TP#{real_ip}\" {user_name}{password::****}@{host_ip}:{host_port}",
|
||||
"desc": []
|
||||
},
|
||||
{
|
||||
|
@ -100,4 +100,4 @@
|
|||
],
|
||||
"selected": "mstsc"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
on scriptRun(argsCmd, argsProfile, argsTitle)
|
||||
on scriptRun(argsCmd, argsProfile, argsTitle, argsInteractiveMode)
|
||||
set theCmd to (argsCmd)
|
||||
set theProfile to (argsProfile)
|
||||
set theTitle to (argsTitle)
|
||||
CommandRun(theCmd, theProfile, theTitle)
|
||||
CommandRun(theCmd, theProfile, theTitle, argsInteractiveMode)
|
||||
end scriptRun
|
||||
|
||||
on CommandRun(theCmd, theProfile, theTitle)
|
||||
on CommandRun(theCmd, theProfile, theTitle, theInteractiveMode)
|
||||
try
|
||||
tell application "iTerm"
|
||||
if it is not running then
|
||||
|
@ -29,8 +29,10 @@ on CommandRun(theCmd, theProfile, theTitle)
|
|||
set name to theTitle
|
||||
set profile to theProfile
|
||||
write text theCmd
|
||||
delay 0.5
|
||||
write text ""
|
||||
if theInteractiveMode = "no" then
|
||||
delay 0.5
|
||||
write text ""
|
||||
end if
|
||||
end tell
|
||||
end tell
|
||||
end tell
|
||||
|
@ -50,8 +52,10 @@ on CommandRun(theCmd, theProfile, theTitle)
|
|||
delay 0.5
|
||||
set name to theTitle
|
||||
write text theCmd
|
||||
delay 0.5
|
||||
write text ""
|
||||
if theInteractiveMode = "no" then
|
||||
delay 0.5
|
||||
write text ""
|
||||
end if
|
||||
end tell
|
||||
end tell
|
||||
end tell
|
||||
|
@ -70,8 +74,10 @@ on CommandRun(theCmd, theProfile, theTitle)
|
|||
delay 0.5
|
||||
set name to theTitle
|
||||
write text theCmd
|
||||
delay 0.5
|
||||
write text ""
|
||||
if theInteractiveMode = "no" then
|
||||
delay 0.5
|
||||
write text ""
|
||||
end if
|
||||
end tell
|
||||
end tell
|
||||
end tell
|
||||
|
|
|
@ -1,26 +1,29 @@
|
|||
on scriptRun(argsCmd, argsProfile, argsTitle)
|
||||
on scriptRun(argsCmd, argsProfile, argsTitle, argsInteractiveMode)
|
||||
set theCmd to (argsCmd)
|
||||
set theProfile to (argsProfile)
|
||||
set theTitle to (argsTitle)
|
||||
CommandRun(theCmd, theProfile, theTitle)
|
||||
CommandRun(theCmd, theProfile, theTitle, argsInteractiveMode)
|
||||
end scriptRun
|
||||
|
||||
on CommandRun(theCmd, theProfile, theTitle)
|
||||
on CommandRun(theCmd, theProfile, theTitle, theInteractiveMode)
|
||||
try
|
||||
tell application "Terminal"
|
||||
if it is not running then
|
||||
--if this is the first time Terminal is running you have specify window 1
|
||||
--if you dont do this you will get two windows and the title wont be set
|
||||
activate
|
||||
activate
|
||||
delay 3.0
|
||||
set newTerm to do script theCmd in window 1
|
||||
set newTerm's current settings to settings set theProfile
|
||||
|
||||
set newTerm's current settings to settings set theProfile
|
||||
set custom title of front window to theTitle
|
||||
|
||||
delay 1.0
|
||||
reopen
|
||||
activate
|
||||
tell application "System Events" to key code 36
|
||||
if theInteractiveMode = "no"
|
||||
delay 1.0
|
||||
reopen
|
||||
activate
|
||||
tell application "System Events" to key code 36
|
||||
end if
|
||||
else
|
||||
--Terminal is running get the window count
|
||||
set windowCount to (count every window)
|
||||
|
@ -31,26 +34,26 @@ on CommandRun(theCmd, theProfile, theTitle)
|
|||
activate
|
||||
|
||||
do script theCmd in window 1
|
||||
|
||||
|
||||
set current settings of selected tab of front window to settings set theProfile
|
||||
set title displays custom title of front window to true
|
||||
set custom title of selected tab of front window to theTitle
|
||||
|
||||
delay 1.0
|
||||
reopen
|
||||
activate
|
||||
tell application "System Events" to key code 36
|
||||
|
||||
if theInteractiveMode = "no"
|
||||
delay 1.0
|
||||
reopen
|
||||
activate
|
||||
tell application "System Events" to key code 36
|
||||
end if
|
||||
else
|
||||
--Terminal is running and we have a window run in a new tab
|
||||
delay 1.0
|
||||
reopen
|
||||
activate
|
||||
|
||||
tell application "System Events"
|
||||
tell process "Terminal"
|
||||
delay 0.5
|
||||
keystroke "t" using {command down}
|
||||
end tell
|
||||
-- Command+T = new tab.
|
||||
key code 17 using {command down}
|
||||
end tell
|
||||
|
||||
reopen
|
||||
|
@ -61,16 +64,14 @@ on CommandRun(theCmd, theProfile, theTitle)
|
|||
set title displays custom title of front window to true
|
||||
set custom title of selected tab of front window to theTitle
|
||||
|
||||
delay 1.0
|
||||
reopen
|
||||
activate
|
||||
tell application "System Events" to key code 36
|
||||
|
||||
if theInteractiveMode = "no"
|
||||
delay 1.0
|
||||
reopen
|
||||
activate
|
||||
tell application "System Events" to key code 36
|
||||
end if
|
||||
end if
|
||||
|
||||
--set current settings of selected tab of front window to settings set theProfile
|
||||
--set title displays custom title of front window to true
|
||||
--set custom title of selected tab of front window to theTitle
|
||||
|
||||
end if
|
||||
|
||||
end tell
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
extern void* g_app;
|
||||
|
||||
int AppDelegate_start_ssh_client (void *_self, const char* cmd_line, const char* term_type, const char* term_theme, const char* term_title);
|
||||
int AppDelegate_start_ssh_client (void *_self, const char* cmd_line, const char* term_type, const char* term_theme, const char* term_title, const char* interactive_mode);
|
||||
int AppDelegate_select_app (void *_self);
|
||||
|
||||
// for cpp global object initialize.
|
||||
|
|
|
@ -29,13 +29,14 @@
|
|||
|
||||
@implementation AppDelegate
|
||||
|
||||
int AppDelegate_start_ssh_client (void *_self, const char* cmd_line, const char* term_type, const char* term_theme, const char* term_title) {
|
||||
int AppDelegate_start_ssh_client (void *_self, const char* cmd_line, const char* term_type, const char* term_theme, const char* term_title, const char* interactive_mode) {
|
||||
NSString* cmdLine = [NSString stringWithUTF8String:cmd_line];
|
||||
NSString* termType = [NSString stringWithUTF8String:term_type];
|
||||
NSString* termTheme = [NSString stringWithUTF8String:term_theme];
|
||||
NSString* termTitle = [NSString stringWithUTF8String:term_title];
|
||||
NSString* interactiveMode = [NSString stringWithUTF8String:interactive_mode];
|
||||
|
||||
return [(__bridge id)_self start_ssh_client:cmdLine termType:termType termTheme:termTheme termTitle:termTitle];
|
||||
return [(__bridge id)_self start_ssh_client:cmdLine termType:termType termTheme:termTheme termTitle:termTitle interactiveMode:interactiveMode];
|
||||
}
|
||||
|
||||
int AppDelegate_select_app (void *_self) {
|
||||
|
@ -118,14 +119,14 @@ int AppDelegate_select_app (void *_self) {
|
|||
}
|
||||
}
|
||||
|
||||
- (int) start_ssh_client:(NSString*)cmd_line termType:(NSString*)term_type termTheme:(NSString*)term_theme termTitle:(NSString*)term_title {
|
||||
- (int) start_ssh_client:(NSString*)cmd_line termType:(NSString*)term_type termTheme:(NSString*)term_theme termTitle:(NSString*)term_title interactiveMode:(NSString*)interactive_mode {
|
||||
NSString *term = [[NSBundle mainBundle] pathForResource:term_type ofType:@"scpt"];
|
||||
|
||||
if(!term)
|
||||
return 1;
|
||||
|
||||
NSString *handlerName = @"scriptRun";
|
||||
NSArray *passParameters = @[cmd_line, term_theme, term_title];
|
||||
NSArray *passParameters = @[cmd_line, term_theme, term_title, interactive_mode];
|
||||
[self runScript:term handler:handlerName parameters:passParameters];
|
||||
|
||||
return 0;
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -31,49 +31,49 @@ void TsWsClient::url_scheme_handler(const std::string& url)
|
|||
{
|
||||
// e.g.:
|
||||
// url: teleport://register?param={"ws_url":"ws://127.0.0.1:7190/ws/assist/","assist_id":1234,"session_id":"tp_5678"}
|
||||
|
||||
|
||||
EXLOGV("url-schema: %s\n", url.c_str());
|
||||
|
||||
std::string protocol;
|
||||
std::string method;
|
||||
std::string param;
|
||||
|
||||
|
||||
std::string::size_type pos_protocol = url.find("://");
|
||||
if (pos_protocol == std::string::npos)
|
||||
{
|
||||
EXLOGE("[ws] invalid url: %s\n", url.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
std::string::size_type pos_method = url.find('?');
|
||||
if (pos_method == std::string::npos)
|
||||
{
|
||||
EXLOGE("[ws] invalid url: %s\n", url.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
protocol.assign(url, 0, pos_protocol);
|
||||
if (protocol != "teleport")
|
||||
{
|
||||
EXLOGE("[ws] invalid protocol: %s\n", protocol.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
method.assign(url, pos_protocol + 3, pos_method - pos_protocol - 3);
|
||||
if(method.empty())
|
||||
{
|
||||
EXLOGE("[ws] no method, what should I do now?\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
param.assign(url, pos_method + 7); // ?param=
|
||||
if (param.empty())
|
||||
{
|
||||
EXLOGE("[ws] invalid protocol: %s\n", protocol.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// decode param with url-decode.
|
||||
size_t len = param.length() * 2;
|
||||
ex_chars sztmp;
|
||||
|
@ -85,13 +85,13 @@ void TsWsClient::url_scheme_handler(const std::string& url)
|
|||
return;
|
||||
}
|
||||
param = &sztmp[0];
|
||||
|
||||
|
||||
EXLOGV("[rpc] method=%s, json_param=%s\n", method.c_str(), param.c_str());
|
||||
|
||||
|
||||
Json::CharReaderBuilder jcrb;
|
||||
std::unique_ptr<Json::CharReader> const jreader(jcrb.newCharReader());
|
||||
const char* str_json_begin = param.c_str();
|
||||
|
||||
|
||||
Json::Value js_root;
|
||||
ex_astr err;
|
||||
if (!jreader->parse(str_json_begin, str_json_begin + param.length(), &js_root, &err))
|
||||
|
@ -104,7 +104,7 @@ void TsWsClient::url_scheme_handler(const std::string& url)
|
|||
EXLOGE("[ws] invalid param, need json object: %s\n", param.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (method == "register")
|
||||
{
|
||||
_process_register(param, js_root);
|
||||
|
@ -127,18 +127,18 @@ void TsWsClient::url_scheme_handler(const std::string& url)
|
|||
void TsWsClient::_process_register(const std::string& param, Json::Value& js_root)
|
||||
{
|
||||
// {"ws_url":"ws://127.0.0.1:7190/ws/assist/","assist_id":1234,"session_id":"tp_5678"}
|
||||
|
||||
|
||||
// check param
|
||||
if (!js_root["ws_url"].isString() || !js_root["assist_id"].isNumeric() || !js_root["session_id"].isString())
|
||||
{
|
||||
EXLOGE("[ws] invalid param: %s\n", param.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
std::string ws_url = js_root["ws_url"].asCString();
|
||||
uint32_t assist_id = js_root["assist_id"].asUInt();
|
||||
std::string session_id = js_root["session_id"].asCString();
|
||||
|
||||
|
||||
std::string protocol;
|
||||
protocol.assign(ws_url, 0, 5);
|
||||
if (protocol == "ws://" || protocol == "wss:/")
|
||||
|
@ -155,7 +155,7 @@ void TsWsClient::_process_register(const std::string& param, Json::Value& js_roo
|
|||
void TsWsClient::_process_run(const std::string& param, Json::Value& js_root)
|
||||
{
|
||||
// wrapper for _rpc_func_run_client().
|
||||
|
||||
|
||||
Json::Value js_param;
|
||||
js_param["method"] = "run";
|
||||
js_param["param"] = js_root;
|
||||
|
@ -168,7 +168,7 @@ void TsWsClient::_process_run(const std::string& param, Json::Value& js_root)
|
|||
void TsWsClient::_process_replay_rdp(const std::string& param, Json::Value& js_root)
|
||||
{
|
||||
// wrapper for _rpc_func_replay_rdp().
|
||||
|
||||
|
||||
Json::Value js_param;
|
||||
js_param["method"] = "replay_rdp";
|
||||
js_param["param"] = js_root;
|
||||
|
@ -181,9 +181,9 @@ void TsWsClient::_process_replay_rdp(const std::string& param, Json::Value& js_r
|
|||
// ============================================================================
|
||||
|
||||
TsWsClient::TsWsClient() :
|
||||
ExThreadBase("ws-client-thread"),
|
||||
m_nc(NULL),
|
||||
m_assist_id(0)
|
||||
ExThreadBase("ws-client-thread"),
|
||||
m_nc(NULL),
|
||||
m_assist_id(0)
|
||||
{
|
||||
mg_mgr_init(&m_mg_mgr, NULL);
|
||||
}
|
||||
|
@ -199,7 +199,7 @@ void TsWsClient::_thread_loop(void)
|
|||
{
|
||||
mg_mgr_poll(&m_mg_mgr, 500);
|
||||
}
|
||||
|
||||
|
||||
EXLOGV("[ws] main loop end.\n");
|
||||
}
|
||||
|
||||
|
@ -207,23 +207,23 @@ void TsWsClient::_register(const std::string& ws_url, uint32_t assist_id, const
|
|||
{
|
||||
if (m_assist_id == 0)
|
||||
m_assist_id = assist_id;
|
||||
|
||||
|
||||
ex_wstr w_ver(TP_ASSIST_VER);
|
||||
ex_astr a_ver;
|
||||
ex_wstr2astr(w_ver, a_ver);
|
||||
|
||||
|
||||
//
|
||||
char msg[256] = {0};
|
||||
ex_strformat(
|
||||
msg, 256, "{\"type\":0,\"method\":\"register\",\"param\":{\"client\":\"assist\",\"sid\":\"%s\",\"request_assist_id\":%u,\"assist_id\":%u,\"assist_ver\":\"%s\"}}",
|
||||
session_id.c_str(), assist_id, m_assist_id, a_ver.c_str());
|
||||
|
||||
msg, 256, "{\"type\":0,\"method\":\"register\",\"param\":{\"client\":\"assist\",\"sid\":\"%s\",\"request_assist_id\":%u,\"assist_id\":%u,\"assist_ver\":\"%s\"}}",
|
||||
session_id.c_str(), assist_id, m_assist_id, a_ver.c_str());
|
||||
|
||||
if (!m_is_running)
|
||||
{
|
||||
// not start yet.
|
||||
std::string url = ws_url;
|
||||
url += msg;
|
||||
|
||||
|
||||
m_nc = mg_connect_ws(&m_mg_mgr, _mg_event_handler, url.c_str(), NULL, NULL);
|
||||
if (!m_nc)
|
||||
{
|
||||
|
@ -231,12 +231,12 @@ void TsWsClient::_register(const std::string& ws_url, uint32_t assist_id, const
|
|||
return;
|
||||
}
|
||||
m_nc->user_data = this;
|
||||
|
||||
|
||||
start();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
EXLOGV("[ws] send: %s\n", msg);
|
||||
mg_send_websocket_frame(m_nc, WEBSOCKET_OP_TEXT, msg, strlen(msg));
|
||||
}
|
||||
|
@ -250,60 +250,60 @@ void TsWsClient::_mg_event_handler(struct mg_connection* nc, int ev, void* ev_da
|
|||
EXLOGE("[ERROR] invalid request.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
switch (ev)
|
||||
{
|
||||
case MG_EV_CONNECT:
|
||||
{
|
||||
int status = *((int*)ev_data);
|
||||
if (status != 0)
|
||||
case MG_EV_CONNECT:
|
||||
{
|
||||
EXLOGE("[ERROR] -- connect to ws server failed: %d\n", status);
|
||||
int status = *((int*)ev_data);
|
||||
if (status != 0)
|
||||
{
|
||||
EXLOGE("[ERROR] -- connect to ws server failed: %d\n", status);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case MG_EV_WEBSOCKET_HANDSHAKE_DONE:
|
||||
{
|
||||
auto* hm = (struct http_message*)ev_data;
|
||||
if (hm->resp_code == 101)
|
||||
|
||||
case MG_EV_WEBSOCKET_HANDSHAKE_DONE:
|
||||
{
|
||||
EXLOGV("-- ws server connected\n");
|
||||
auto* hm = (struct http_message*)ev_data;
|
||||
if (hm->resp_code == 101)
|
||||
{
|
||||
EXLOGV("-- ws server connected\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
EXLOGE("[ERROR] -- connect to ws server failed, HTTP code: %d\n", hm->resp_code);
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
|
||||
|
||||
case MG_EV_WEBSOCKET_FRAME:
|
||||
{
|
||||
EXLOGE("[ERROR] -- connect to ws server failed, HTTP code: %d\n", hm->resp_code);
|
||||
// on_message().
|
||||
auto* wm = (struct websocket_message*)ev_data;
|
||||
// EXLOGV("%d: %s\n", wm->size, wm->data);
|
||||
std::string message;
|
||||
message.assign((const char*)wm->data, wm->size);
|
||||
std::string buf;
|
||||
_this->_on_message(message, buf);
|
||||
|
||||
if (!buf.empty())
|
||||
{
|
||||
mg_send_websocket_frame(nc, WEBSOCKET_OP_TEXT, buf.c_str(), buf.length());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case MG_EV_WEBSOCKET_FRAME:
|
||||
{
|
||||
// on_message().
|
||||
auto* wm = (struct websocket_message*)ev_data;
|
||||
// EXLOGV("%d: %s\n", wm->size, wm->data);
|
||||
std::string message;
|
||||
message.assign((const char*)wm->data, wm->size);
|
||||
std::string buf;
|
||||
_this->_on_message(message, buf);
|
||||
|
||||
if (!buf.empty())
|
||||
|
||||
|
||||
case MG_EV_CLOSE:
|
||||
{
|
||||
mg_send_websocket_frame(nc, WEBSOCKET_OP_TEXT, buf.c_str(), buf.length());
|
||||
EXLOGV("-- ws server disconnected\n");
|
||||
_this->m_need_stop = true;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case MG_EV_CLOSE:
|
||||
{
|
||||
EXLOGV("-- ws server disconnected\n");
|
||||
_this->m_need_stop = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -328,7 +328,7 @@ void TsWsClient::_create_response(ex_astr& buf, const AssistMessage& msg_ret, in
|
|||
js_ret["code"] = err_code;
|
||||
js_ret["message"] = message;
|
||||
js_ret["data"] = data;
|
||||
|
||||
|
||||
Json::StreamWriterBuilder jwb;
|
||||
jwb["indentation"] = ""; // 压缩格式,没有换行和不必要的空白字符
|
||||
std::unique_ptr<Json::StreamWriter> js_writer(jwb.newStreamWriter());
|
||||
|
@ -349,15 +349,15 @@ void TsWsClient::_on_message(const std::string& message, std::string& buf)
|
|||
// "protocol_sub_type":200,"protocol_flag":4294967295
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
EXLOGV("on_message: %s\n", message.c_str());
|
||||
|
||||
AssistMessage msg_req;
|
||||
|
||||
|
||||
Json::CharReaderBuilder jrb;
|
||||
std::unique_ptr<Json::CharReader> const js_reader(jrb.newCharReader());
|
||||
const char* str_json_begin = message.c_str();
|
||||
|
||||
|
||||
Json::Value js_root;
|
||||
ex_astr err;
|
||||
if (!js_reader->parse(str_json_begin, str_json_begin + message.length(), &js_root, &err))
|
||||
|
@ -370,40 +370,40 @@ void TsWsClient::_on_message(const std::string& message, std::string& buf)
|
|||
_create_response(buf, msg_req, TPE_PARAM);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (js_root["type"].isNull() || !js_root["type"].isInt())
|
||||
{
|
||||
_create_response(buf, msg_req, TPE_PARAM);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int cmd_type = js_root["type"].asInt();
|
||||
if (!(cmd_type == MESSAGE_TYPE_REQUEST || cmd_type == MESSAGE_TYPE_RESPONSE))
|
||||
{
|
||||
_create_response(buf, msg_req, TPE_PARAM);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 收到的信息已经是“返回值”了,说明已经是一条命令的结束了,不用继续处理
|
||||
// todo: 可能需要记录日志,或者展示结果。
|
||||
if (cmd_type == MESSAGE_TYPE_RESPONSE)
|
||||
return;
|
||||
|
||||
|
||||
if (js_root["method"].isNull() || !js_root["method"].isString() || js_root["command_id"].isNull() || !js_root["command_id"].isInt())
|
||||
{
|
||||
_create_response(buf, msg_req, TPE_PARAM);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
msg_req.command_id = js_root["command_id"].asInt();
|
||||
msg_req.method = js_root["method"].asString();
|
||||
|
||||
|
||||
if (msg_req.command_id == 0 || msg_req.method.empty())
|
||||
{
|
||||
_create_response(buf, msg_req, TPE_PARAM);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (msg_req.method == "run")
|
||||
{
|
||||
_rpc_func_run_client(buf, msg_req, js_root);
|
||||
|
@ -436,7 +436,7 @@ void TsWsClient::_rpc_func_get_config(ex_astr& buf, AssistMessage& msg_req, Json
|
|||
Json::Value& ret = g_cfg.get_root();
|
||||
if(ret["os_type"].isNull())
|
||||
ret["os_type"] = "macos";
|
||||
|
||||
|
||||
_create_response(buf, msg_req, TPE_OK, "", ret);
|
||||
}
|
||||
|
||||
|
@ -448,12 +448,12 @@ void TsWsClient::_rpc_func_set_config(ex_astr& buf, AssistMessage& msg_req, Json
|
|||
return;
|
||||
}
|
||||
Json::Value& js_param = js_root["param"];
|
||||
|
||||
|
||||
Json::StreamWriterBuilder jwb;
|
||||
std::unique_ptr<Json::StreamWriter> js_writer(jwb.newStreamWriter());
|
||||
ex_aoss os;
|
||||
js_writer->write(js_param, &os);
|
||||
|
||||
|
||||
if (!g_cfg.save(os.str()))
|
||||
_create_response(buf, msg_req, TPE_FAILED);
|
||||
else
|
||||
|
@ -476,26 +476,26 @@ void TsWsClient::_rpc_func_replay_rdp(ex_astr& buf, AssistMessage& msg_req, Json
|
|||
// "sid":"tp_1622707094_1c8e4fd4006c6ad5"
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
if (js_root["param"].isNull() || !js_root["param"].isObject())
|
||||
{
|
||||
_create_response(buf, msg_req, TPE_PARAM);
|
||||
return;
|
||||
}
|
||||
Json::Value& js_param = js_root["param"];
|
||||
|
||||
|
||||
// check param
|
||||
if (!js_param["rid"].isNumeric()
|
||||
|| !js_param["web"].isString()
|
||||
|| !js_param["sid"].isString()
|
||||
)
|
||||
)
|
||||
{
|
||||
_create_response(buf, msg_req, TPE_PARAM);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ex_astrs s_argv;
|
||||
|
||||
|
||||
ex_wstr w_exec_file = g_env.m_bundle_path;
|
||||
ex_path_join(w_exec_file, false, L"Contents", L"Resources", L"tp-player.app", L"Contents", L"MacOS", L"tp-player", nullptr);
|
||||
// ex_path_join(w_exec_file, false, L"tp-player.app", L"Contents", L"MacOS", L"tp-player", nullptr);
|
||||
|
@ -503,16 +503,16 @@ void TsWsClient::_rpc_func_replay_rdp(ex_astr& buf, AssistMessage& msg_req, Json
|
|||
ex_wstr2astr(w_exec_file, exec_file);
|
||||
|
||||
s_argv.push_back(exec_file);
|
||||
|
||||
|
||||
|
||||
|
||||
int rid = js_param["rid"].asInt();
|
||||
ex_astr a_url_base = js_param["web"].asCString();
|
||||
ex_astr a_sid = js_param["sid"].asCString();
|
||||
|
||||
|
||||
char cmd_args[1024] = { 0 };
|
||||
ex_strformat(cmd_args, 1023, "%s/%s/%d", a_url_base.c_str(), a_sid.c_str(), rid);
|
||||
s_argv.push_back(cmd_args);
|
||||
|
||||
|
||||
ex_wstr w_cmd_args;
|
||||
ex_astr2wstr(cmd_args, w_cmd_args);
|
||||
|
||||
|
@ -520,47 +520,47 @@ void TsWsClient::_rpc_func_replay_rdp(ex_astr& buf, AssistMessage& msg_req, Json
|
|||
ex_strformat(total_cmd, 1023, "%s %s", exec_file.c_str(), cmd_args);
|
||||
|
||||
Json::Value js_ret;
|
||||
|
||||
|
||||
ex_astr utf8_path;
|
||||
//ex_wstr2astr(total_cmd, utf8_path, EX_CODEPAGE_UTF8);
|
||||
js_ret["cmdline"] = total_cmd;
|
||||
|
||||
|
||||
// EXLOGD(utf8_path.c_str());
|
||||
|
||||
|
||||
// for macOS, Create Process should be fork()/exec()...
|
||||
int ret_code = TPE_OK;
|
||||
pid_t processId;
|
||||
if ((processId = fork()) == 0) {
|
||||
|
||||
|
||||
int i = 0;
|
||||
char** _argv = (char**)calloc(s_argv.size()+1, sizeof(char*));
|
||||
if (!_argv)
|
||||
return;
|
||||
|
||||
|
||||
for (i = 0; i < s_argv.size(); ++i)
|
||||
{
|
||||
_argv[i] = ex_strdup(s_argv[i].c_str());
|
||||
}
|
||||
_argv[i] = NULL;
|
||||
|
||||
|
||||
execv(exec_file.c_str(), _argv);
|
||||
|
||||
|
||||
for(i = 0; i < s_argv.size(); ++i) {
|
||||
if(_argv[i] != NULL) {
|
||||
free(_argv[i]);
|
||||
}
|
||||
}
|
||||
free(_argv);
|
||||
|
||||
|
||||
} else if (processId < 0) {
|
||||
ret_code = TPE_FAILED;
|
||||
} else {
|
||||
ret_code = TPE_OK;
|
||||
}
|
||||
|
||||
|
||||
// _create_json_ret(buf, root_ret);
|
||||
_create_response(buf, msg_req, ret_code, "", js_ret);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void TsWsClient::_rpc_func_run_client(ex_astr& buf, AssistMessage& msg_req, Json::Value& js_root)
|
||||
|
@ -573,71 +573,84 @@ void TsWsClient::_rpc_func_run_client(ex_astr& buf, AssistMessage& msg_req, Json
|
|||
// "protocol_sub_type":200,"protocol_flag":4294967295
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
if (js_root["param"].isNull() || !js_root["param"].isObject())
|
||||
{
|
||||
_create_response(buf, msg_req, TPE_PARAM);
|
||||
return;
|
||||
}
|
||||
Json::Value& js_param = js_root["param"];
|
||||
|
||||
|
||||
// check param
|
||||
if (!js_param["teleport_ip"].isString()
|
||||
|| !js_param["teleport_port"].isNumeric() || !js_param["remote_host_ip"].isString()
|
||||
|| !js_param["session_id"].isString() || !js_param["protocol_type"].isNumeric() || !js_param["protocol_sub_type"].isNumeric()
|
||||
|| !js_param["protocol_flag"].isNumeric()
|
||||
)
|
||||
)
|
||||
{
|
||||
_create_response(buf, msg_req, TPE_PARAM);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const char* interactive_mode = "no";
|
||||
bool is_interactive_mode = false;
|
||||
if(!js_param["is_interactive"].isNull()) {
|
||||
if(!js_param["is_interactive"].isBool()) {
|
||||
_create_response(buf, msg_req, TPE_PARAM);
|
||||
return;
|
||||
}
|
||||
if(js_param["is_interactive"].asBool()) {
|
||||
interactive_mode = "yes";
|
||||
is_interactive_mode = true;
|
||||
}
|
||||
}
|
||||
|
||||
int pro_type = js_param["protocol_type"].asUInt();
|
||||
int pro_sub = js_param["protocol_sub_type"].asInt();
|
||||
ex_u32 protocol_flag = js_param["protocol_flag"].asUInt();
|
||||
|
||||
|
||||
ex_astr teleport_ip = js_param["teleport_ip"].asCString();
|
||||
int teleport_port = js_param["teleport_port"].asUInt();
|
||||
char _port[64] = {0};
|
||||
ex_strformat(_port, 64, "%d", teleport_port);
|
||||
ex_astr str_teleport_port = _port;
|
||||
|
||||
|
||||
ex_astr real_host_ip = js_param["remote_host_ip"].asCString();
|
||||
ex_astr real_host_name = js_param["remote_host_name"].asCString();
|
||||
ex_astr sid = js_param["session_id"].asCString();
|
||||
|
||||
|
||||
|
||||
|
||||
ex_astr s_exec;
|
||||
ex_astr s_arg;
|
||||
ex_astrs s_argv;
|
||||
|
||||
|
||||
|
||||
|
||||
if (pro_type == TP_PROTOCOL_TYPE_RDP)
|
||||
{
|
||||
//==============================================
|
||||
// RDP
|
||||
//==============================================
|
||||
|
||||
|
||||
if (g_cfg.rdp.application.length() == 0)
|
||||
{
|
||||
_create_response(buf, msg_req, TPE_NOT_EXISTS, "助手未配置本地RDP客户端,请检查您的助手设置。");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!ex_is_file_exists(g_cfg.rdp.application.c_str()))
|
||||
{
|
||||
_create_response(buf, msg_req, TPE_NOT_EXISTS, "无法定位助手配置的RDP客户端,请检查您的助手设置。");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
bool flag_clipboard = ((protocol_flag & TP_FLAG_RDP_CLIPBOARD) == TP_FLAG_RDP_CLIPBOARD);
|
||||
bool flag_disk = ((protocol_flag & TP_FLAG_RDP_DISK) == TP_FLAG_RDP_DISK);
|
||||
bool flag_console = ((protocol_flag & TP_FLAG_RDP_CONSOLE) == TP_FLAG_RDP_CONSOLE);
|
||||
|
||||
|
||||
int rdp_w = 800;
|
||||
int rdp_h = 640;
|
||||
bool rdp_console = false;
|
||||
|
||||
|
||||
if (!js_param["rdp_width"].isNull())
|
||||
{
|
||||
if (js_param["rdp_width"].isNumeric())
|
||||
|
@ -650,7 +663,7 @@ void TsWsClient::_rpc_func_run_client(ex_astr& buf, AssistMessage& msg_req, Json
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!js_param["rdp_height"].isNull())
|
||||
{
|
||||
if (js_param["rdp_height"].isNumeric())
|
||||
|
@ -663,7 +676,7 @@ void TsWsClient::_rpc_func_run_client(ex_astr& buf, AssistMessage& msg_req, Json
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!js_param["rdp_console"].isNull())
|
||||
{
|
||||
if (js_param["rdp_console"].isBool())
|
||||
|
@ -676,11 +689,11 @@ void TsWsClient::_rpc_func_run_client(ex_astr& buf, AssistMessage& msg_req, Json
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!flag_console)
|
||||
rdp_console = false;
|
||||
|
||||
|
||||
|
||||
|
||||
size_t split_pos = sid.length() - 2;
|
||||
ex_astr real_sid = sid.substr(0, split_pos);
|
||||
ex_astr str_pwd_len = sid.substr(split_pos, sid.length());
|
||||
|
@ -692,9 +705,9 @@ void TsWsClient::_rpc_func_run_client(ex_astr& buf, AssistMessage& msg_req, Json
|
|||
{
|
||||
szPwd[i] = '*';
|
||||
}
|
||||
|
||||
|
||||
//ex_astr2wstr(real_sid, w_sid);
|
||||
|
||||
|
||||
//w_exe_path = _T("\"");
|
||||
//w_exe_path += g_cfg.rdp_app + _T("\" ");
|
||||
//w_exe_path += g_cfg.rdp_cmdline;
|
||||
|
@ -704,10 +717,10 @@ void TsWsClient::_rpc_func_run_client(ex_astr& buf, AssistMessage& msg_req, Json
|
|||
//s_exec = "/usr/local/Cellar/freerdp/1.0.2_1/bin/xfreerdp";
|
||||
s_exec = g_cfg.rdp.application;
|
||||
s_arg = g_cfg.rdp.cmdline;
|
||||
|
||||
|
||||
sid = "02" + real_sid;
|
||||
// s_argv.push_back("/f");
|
||||
|
||||
|
||||
s_argv.push_back("/sec:tls");
|
||||
s_argv.push_back("-wallpaper");
|
||||
s_argv.push_back("-themes");
|
||||
|
@ -715,20 +728,20 @@ void TsWsClient::_rpc_func_run_client(ex_astr& buf, AssistMessage& msg_req, Json
|
|||
s_argv.push_back("/cert-ignore");
|
||||
// Automatically accept certificate on first connect
|
||||
s_argv.push_back("/cert-tofu");
|
||||
|
||||
|
||||
ex_astr _tmp_pass = "/p:PLACEHOLDER";
|
||||
//_tmp_pass += szPwd;
|
||||
s_argv.push_back(_tmp_pass);
|
||||
|
||||
|
||||
//#if 0
|
||||
//s_argv.push_back(s_exec.c_str());
|
||||
|
||||
|
||||
{
|
||||
// ex_astr username = "02" + real_sid;
|
||||
// s_argv.push_back("/u:");
|
||||
// s_argv.push_back(username.c_str());
|
||||
|
||||
|
||||
|
||||
|
||||
if (rdp_w == 0 || rdp_h == 0)
|
||||
{
|
||||
s_argv.push_back("/f");
|
||||
|
@ -742,20 +755,20 @@ void TsWsClient::_rpc_func_run_client(ex_astr& buf, AssistMessage& msg_req, Json
|
|||
char sz_width[64] = {0};
|
||||
ex_strformat(sz_width, 63, "/w:%d", rdp_w);
|
||||
s_argv.push_back(sz_width);
|
||||
|
||||
|
||||
char sz_height[64] = {0};
|
||||
ex_strformat(sz_height, 63, "/h:%d", rdp_h);
|
||||
s_argv.push_back(sz_height);
|
||||
}
|
||||
|
||||
|
||||
if (flag_console && rdp_console)
|
||||
s_argv.push_back("/admin");
|
||||
|
||||
|
||||
// if(flag_clipboard)
|
||||
// s_argv.push_back("+clipboard");
|
||||
// else
|
||||
// s_argv.push_back("-clipboard");
|
||||
|
||||
|
||||
// if(flag_disk)
|
||||
// s_argv.push_back("+drives");
|
||||
// else
|
||||
|
@ -774,52 +787,52 @@ void TsWsClient::_rpc_func_run_client(ex_astr& buf, AssistMessage& msg_req, Json
|
|||
//==============================================
|
||||
// SSH
|
||||
//==============================================
|
||||
|
||||
|
||||
if (pro_sub == TP_PROTOCOL_TYPE_SSH_SHELL)
|
||||
{
|
||||
if (g_cfg.ssh.name == "terminal" || g_cfg.ssh.name == "iterm2")
|
||||
{
|
||||
char szCmd[1024] = {0};
|
||||
ex_strformat(szCmd, 1023, "ssh %s@%s -p %d -o \"StrictHostKeyChecking no\"", sid.c_str(), teleport_ip.c_str(), teleport_port);
|
||||
|
||||
|
||||
char szTitle[128] = {0};
|
||||
ex_strformat(szTitle, 127, "TP#%s", real_host_ip.c_str());
|
||||
|
||||
int ret = AppDelegate_start_ssh_client(g_app, szCmd, g_cfg.ssh.name.c_str(), g_cfg.ssh.cmdline.c_str(), szTitle);
|
||||
|
||||
int ret = AppDelegate_start_ssh_client(g_app, szCmd, g_cfg.ssh.name.c_str(), g_cfg.ssh.cmdline.c_str(), szTitle, interactive_mode);
|
||||
if (ret == 0)
|
||||
_create_response(buf, msg_req, TPE_OK);
|
||||
else
|
||||
_create_response(buf, msg_req, TPE_FAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (g_cfg.ssh.application.length() == 0)
|
||||
{
|
||||
_create_response(buf, msg_req, TPE_NOT_EXISTS);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
s_exec = g_cfg.ssh.application;
|
||||
s_argv.push_back(s_exec.c_str());
|
||||
|
||||
|
||||
s_arg = g_cfg.ssh.cmdline;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
// sorry, SFTP not supported yet for macOS.
|
||||
// _create_json_ret(buf, TPE_NOT_IMPLEMENT);
|
||||
// return;
|
||||
|
||||
|
||||
if (g_cfg.sftp.application.length() == 0)
|
||||
{
|
||||
_create_response(buf, msg_req, TPE_NOT_EXISTS);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
s_exec = g_cfg.sftp.application;
|
||||
s_argv.push_back(s_exec.c_str());
|
||||
|
||||
|
||||
s_arg = g_cfg.sftp.cmdline;
|
||||
}
|
||||
}
|
||||
|
@ -828,46 +841,96 @@ void TsWsClient::_rpc_func_run_client(ex_astr& buf, AssistMessage& msg_req, Json
|
|||
//==============================================
|
||||
// TELNET
|
||||
//==============================================
|
||||
|
||||
|
||||
// sorry, TELNET not supported yet for macOS.
|
||||
// _create_json_ret(buf, TPE_NOT_IMPLEMENT);
|
||||
// return;
|
||||
|
||||
|
||||
g_cfg.telnet.name = "iterm2";
|
||||
|
||||
|
||||
if (g_cfg.telnet.name == "terminal" || g_cfg.telnet.name == "iterm2")
|
||||
{
|
||||
char szCmd[1024] = {0};
|
||||
ex_strformat(szCmd, 1023, "telnet -l %s %s %d", sid.c_str(), teleport_ip.c_str(), teleport_port);
|
||||
|
||||
|
||||
char szTitle[128] = {0};
|
||||
ex_strformat(szTitle, 127, "TP#%s", real_host_ip.c_str());
|
||||
|
||||
int ret = AppDelegate_start_ssh_client(g_app, szCmd, g_cfg.telnet.name.c_str(), g_cfg.telnet.cmdline.c_str(), szTitle);
|
||||
|
||||
int ret = AppDelegate_start_ssh_client(g_app, szCmd, g_cfg.telnet.name.c_str(), g_cfg.telnet.cmdline.c_str(), szTitle, interactive_mode);
|
||||
if (ret == 0)
|
||||
_create_response(buf, msg_req, TPE_OK);
|
||||
else
|
||||
_create_response(buf, msg_req, TPE_FAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (g_cfg.telnet.application.length() == 0)
|
||||
{
|
||||
_create_response(buf, msg_req, TPE_NOT_EXISTS);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
s_exec = g_cfg.telnet.application;
|
||||
s_argv.push_back(s_exec.c_str());
|
||||
|
||||
|
||||
s_arg = g_cfg.telnet.cmdline;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//---- split s_arg and push to s_argv ---
|
||||
ex_astr::size_type p1 = 0;
|
||||
ex_astr::size_type p2 = 0;
|
||||
ex_astr tmp = s_arg;
|
||||
ex_astr tmp;
|
||||
|
||||
for(;;){
|
||||
p1 = s_arg.find("{password:");
|
||||
if(p1 != ex_astr::npos) {
|
||||
p2 = s_arg.find('}', p1+10);
|
||||
if(p2 == ex_astr::npos) {
|
||||
_create_response(buf, msg_req, TPE_PARAM);
|
||||
return;
|
||||
}
|
||||
|
||||
if(is_interactive_mode) {
|
||||
// 如果需要用户自己输入密码,则客户端命令行就不能带密码字段,需要抹去这个参数
|
||||
s_arg.erase(p1, p2-p1+1);
|
||||
}
|
||||
else{
|
||||
s_arg.erase(p2, 1);
|
||||
s_arg.erase(p1, 10);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(;;){
|
||||
p1 = s_arg.find("{interactive:");
|
||||
if(p1 != ex_astr::npos) {
|
||||
p2 = s_arg.find('}', p1+13);
|
||||
if(p2 == ex_astr::npos) {
|
||||
_create_response(buf, msg_req, TPE_PARAM);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!is_interactive_mode) {
|
||||
// 如果无需用户自己输入密码,则需要抹去这个参数
|
||||
s_arg.erase(p1, p2-p1+1);
|
||||
}
|
||||
else{
|
||||
s_arg.erase(p2, 1);
|
||||
s_arg.erase(p1, 13);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
tmp = s_arg;
|
||||
for (;;)
|
||||
{
|
||||
ex_remove_white_space(tmp, EX_RSC_BEGIN);
|
||||
|
@ -875,48 +938,48 @@ void TsWsClient::_rpc_func_run_client(ex_astr& buf, AssistMessage& msg_req, Json
|
|||
{
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (tmp[0] == '"')
|
||||
{
|
||||
p1 = 1;
|
||||
p2 = tmp.find('"', p1);
|
||||
|
||||
|
||||
if (p2 == ex_astr::npos)
|
||||
{
|
||||
_create_response(buf, msg_req, TPE_PARAM);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ex_astr _t;
|
||||
_t.assign(tmp, p1, p2 - p1);
|
||||
tmp.erase(0, p2 + 2);
|
||||
|
||||
|
||||
s_argv.push_back(_t);
|
||||
}
|
||||
else
|
||||
{
|
||||
p1 = 0;
|
||||
p2 = tmp.find(' ', p1);
|
||||
|
||||
|
||||
if (p2 == ex_astr::npos)
|
||||
{
|
||||
s_argv.push_back(tmp);
|
||||
tmp.clear();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
ex_astr _t;
|
||||
_t.assign(tmp, p1, p2 - p1);
|
||||
tmp.erase(0, p2 + 1);
|
||||
|
||||
|
||||
s_argv.push_back(_t);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Json::Value js_data;
|
||||
ex_astr utf8_path = s_exec;
|
||||
|
||||
|
||||
ex_astrs::iterator it = s_argv.begin();
|
||||
for (; it != s_argv.end(); ++it)
|
||||
{
|
||||
|
@ -926,31 +989,31 @@ void TsWsClient::_rpc_func_run_client(ex_astr& buf, AssistMessage& msg_req, Json
|
|||
ex_replace_all((*it), "{real_ip}", real_host_ip);
|
||||
ex_replace_all((*it), "{host_name}", real_host_name);
|
||||
//ex_replace_all(utf8_path, _T("{assist_tools_path}"), g_env.m_tools_path.c_str());
|
||||
|
||||
|
||||
utf8_path += " ";
|
||||
utf8_path += (*it);
|
||||
}
|
||||
|
||||
|
||||
js_data["path"] = utf8_path;
|
||||
|
||||
|
||||
// for macOS, Create Process should be fork()/exec()...
|
||||
pid_t processId;
|
||||
if ((processId = fork()) == 0)
|
||||
{
|
||||
|
||||
|
||||
int i = 0;
|
||||
char** _argv = (char**)calloc(s_argv.size() + 1, sizeof(char*));
|
||||
if (!_argv)
|
||||
return;
|
||||
|
||||
|
||||
for (i = 0; i < s_argv.size(); ++i)
|
||||
{
|
||||
_argv[i] = ex_strdup(s_argv[i].c_str());
|
||||
}
|
||||
_argv[i] = NULL;
|
||||
|
||||
|
||||
execv(s_exec.c_str(), _argv);
|
||||
|
||||
|
||||
for (i = 0; i < s_argv.size(); ++i)
|
||||
{
|
||||
if (_argv[i] != NULL)
|
||||
|
|
|
@ -440,7 +440,7 @@ void TsHttpRpc::_rpc_func_enc(const Json::Value& json_param, ex_astr& buf)
|
|||
is_enc = false;
|
||||
|
||||
plain_text = json_param["p"].asCString();
|
||||
if (plain_text.length() == 0)
|
||||
if (plain_text.empty())
|
||||
{
|
||||
_create_json_ret(buf, TPE_PARAM);
|
||||
return;
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
#include <mbedtls/sha1.h>
|
||||
#include <teleport_const.h>
|
||||
|
||||
// 临时会话ID有效期,毫秒
|
||||
#define TEMP_SESSION_ID_VALID_TIME 60000
|
||||
|
||||
TsSessionManager g_session_mgr;
|
||||
|
||||
TsSessionManager::TsSessionManager() :
|
||||
|
@ -44,7 +47,7 @@ void TsSessionManager::_remove_expired_connect_info()
|
|||
for (; it != m_connections.end();)
|
||||
{
|
||||
//EXLOGD("[core] check expired connect info: [%s] %d, %d %d %d\n", it->first.c_str(), it->second->ref_count, int(_now), int(it->second->ticket_start), int(_now - it->second->ticket_start));
|
||||
if (it->second->ref_count == 0 && _now - 15000 > it->second->ticket_start)
|
||||
if (it->second->ref_count == 0 && _now - TEMP_SESSION_ID_VALID_TIME > it->second->ticket_start)
|
||||
{
|
||||
EXLOGD("[core] remove connection info, because timeout: %s\n", it->first.c_str());
|
||||
delete it->second;
|
||||
|
@ -100,7 +103,8 @@ bool TsSessionManager::free_connect_info(const ex_astr& sid)
|
|||
|
||||
it->second->ref_count--;
|
||||
|
||||
// 对于RDP来说,此时不要移除连接信息,系统自带RDP客户端在第一次连接时进行协议协商,然后马上会断开,之后立即重新连接一次(第二次连接之前可能会提示证书信息,如果用户长时间不操作,可能会导致超时)。
|
||||
// 对于RDP来说,此时不要移除连接信息,系统自带RDP客户端在第一次连接时进行协议协商,然后马上会断开,之后立即重新连接
|
||||
// 一次(第二次连接之前可能会提示证书信息,如果用户长时间不操作,可能会导致超时)。
|
||||
// 因此,我们将其引用计数减低,并更新一下最后访问时间,让定时器来移除它。
|
||||
if (it->second->protocol_type != TP_PROTOCOL_TYPE_RDP)
|
||||
{
|
||||
|
@ -116,10 +120,10 @@ bool TsSessionManager::free_connect_info(const ex_astr& sid)
|
|||
{
|
||||
if (it->second->ref_count == 1)
|
||||
it->second->ref_count = 0;
|
||||
it->second->ticket_start = ex_get_tick_count() + 45000; // 我们将时间向后移动45秒,这样如果没有发生RDP的第二次连接,这个连接信息就会在一分钟后被清除。
|
||||
// 我们将启动时间向后一段,这样如果没有发生RDP的第二次连接,这个连接信息过一会儿就会被清除。
|
||||
it->second->ticket_start = ex_get_tick_count() + TEMP_SESSION_ID_VALID_TIME;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ int ts_web_rpc_get_conn_info(int conn_id, TS_CONNECT_INFO& info)
|
|||
EXLOGE("[core] get conn info from web-server failed: can not connect to web-server.\n");
|
||||
return TPE_NETWORK;
|
||||
}
|
||||
if (body.length() == 0)
|
||||
if (body.empty())
|
||||
{
|
||||
EXLOGE("[core] get conn info from web-server failed: got nothing.\n");
|
||||
return TPE_NETWORK;
|
||||
|
@ -191,10 +191,10 @@ int ts_web_rpc_get_conn_info(int conn_id, TS_CONNECT_INFO& info)
|
|||
// 注意,account_id可以为-1,表示这是一次测试连接。
|
||||
// if (user_id <= 0 || host_id <= 0
|
||||
// ||
|
||||
if (user_username.length() == 0
|
||||
|| host_ip.length() == 0 || conn_ip.length() == 0 || client_ip.length() == 0
|
||||
if (user_username.empty()
|
||||
|| host_ip.empty() || conn_ip.empty() || client_ip.empty()
|
||||
|| conn_port <= 0 || conn_port >= 65535
|
||||
|| acc_username.length() == 0
|
||||
|| acc_username.empty()
|
||||
|| !(protocol_type == TP_PROTOCOL_TYPE_RDP || protocol_type == TP_PROTOCOL_TYPE_SSH || protocol_type == TP_PROTOCOL_TYPE_TELNET)
|
||||
|| !(auth_type == TP_AUTH_TYPE_NONE || auth_type == TP_AUTH_TYPE_PASSWORD || auth_type == TP_AUTH_TYPE_PRIVATE_KEY)
|
||||
)
|
||||
|
@ -202,10 +202,14 @@ int ts_web_rpc_get_conn_info(int conn_id, TS_CONNECT_INFO& info)
|
|||
return TPE_PARAM;
|
||||
}
|
||||
|
||||
if (auth_type != TP_AUTH_TYPE_NONE && acc_secret.length() == 0)
|
||||
{
|
||||
// 认证方式为密码时,允许不设置密码,而是连接时由用户手动输入
|
||||
if(acc_secret.empty() && !(auth_type == TP_AUTH_TYPE_NONE || auth_type == TP_AUTH_TYPE_PASSWORD))
|
||||
return TPE_PARAM;
|
||||
}
|
||||
|
||||
// if (auth_type != TP_AUTH_TYPE_NONE && acc_secret.length() == 0)
|
||||
// {
|
||||
// return TPE_PARAM;
|
||||
// }
|
||||
|
||||
if (_enc && !acc_secret.empty())
|
||||
{
|
||||
|
|
|
@ -15,8 +15,8 @@ SshSession::SshSession(SshProxy* proxy, ssh_session rs_tp2cli, uint32_t dbg_id,
|
|||
m_conn_info(nullptr),
|
||||
m_conn_port(0),
|
||||
m_flags(0),
|
||||
m_auth_type(TP_AUTH_TYPE_NONE),
|
||||
m_allow_user_input_password(false)
|
||||
m_auth_type(TP_AUTH_TYPE_NONE)
|
||||
// , m_allow_user_input_password(false)
|
||||
{
|
||||
ex_strformat(m_dbg_name, 128, "ssh-%d", dbg_id);
|
||||
ex_strformat(m_dbg_client, 128, "%s:%d", client_ip, client_port);
|
||||
|
@ -455,6 +455,7 @@ int SshSession::_on_auth_password_request(ssh_session /*session*/, const char* u
|
|||
int SshSession::_do_auth(const char* user, const char* secret)
|
||||
{
|
||||
EXLOGD("[%s] authenticating, user: %s\n", m_dbg_name.c_str(), user);
|
||||
// EXLOGD("[%s] authenticating, user: %s, secret: %s\n", m_dbg_name.c_str(), user, secret);
|
||||
|
||||
// v3.6.0
|
||||
// 场景
|
||||
|
@ -591,12 +592,12 @@ int SshSession::_do_auth(const char* user, const char* secret)
|
|||
if (m_acc_secret.empty())
|
||||
{
|
||||
// 如果TP中未设置远程账号密码,表示允许用户自行输入密码
|
||||
m_allow_user_input_password = true;
|
||||
// m_allow_user_input_password = true;
|
||||
|
||||
// 如果传入的password为特定值,应该是由助手调用客户端,填写的密码
|
||||
// 直接返回认证失败,这样客户端会让用户输入密码
|
||||
if (0 == strcmp(secret, "INTERACTIVE_USER"))
|
||||
return SSH_AUTH_DENIED;
|
||||
// // 如果传入的password为特定值,应该是由助手调用客户端,填写的密码
|
||||
// // 直接返回认证失败,这样客户端会让用户输入密码
|
||||
// if (0 == strcmp(secret, "INTERACTIVE_USER"))
|
||||
// return SSH_AUTH_DENIED;
|
||||
|
||||
// 用户脱离TP-WEB,直接使用客户端输入的密码
|
||||
m_acc_secret = secret;
|
||||
|
@ -761,7 +762,7 @@ int SshSession::_do_auth(const char* user, const char* secret)
|
|||
|
||||
// about 'echo':
|
||||
// This is an optional variable. You can obtain a boolean if the user input should be echoed or
|
||||
// hidden. For passwords it is usually hidden.
|
||||
// hidden. For password it is usually hidden.
|
||||
|
||||
EXLOGV("[%s] interactive login prompt(%s): %s\n", m_dbg_name.c_str(), echo ? "hidden" : "not hidden", prompt);
|
||||
if (echo)
|
||||
|
|
|
@ -151,7 +151,7 @@ private:
|
|||
std::string m_acc_secret;
|
||||
uint32_t m_flags;
|
||||
int m_auth_type;
|
||||
bool m_allow_user_input_password;
|
||||
// bool m_allow_user_input_password;
|
||||
|
||||
bool m_first_auth;
|
||||
// 远程主机认证是否通过
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -33,7 +33,7 @@ $app.create_controls = function (cb_stack) {
|
|||
//-------------------------------
|
||||
// 主机列表表格
|
||||
//-------------------------------
|
||||
var table_host_options = {
|
||||
let table_host_options = {
|
||||
dom_id: 'table-host',
|
||||
data_source: {
|
||||
type: 'ajax-post',
|
||||
|
@ -190,7 +190,7 @@ $app.create_controls = function (cb_stack) {
|
|||
$app.dom.dlg_import_asset.modal({backdrop: 'static'});
|
||||
});
|
||||
$app.dom.chkbox_host_select_all.click(function () {
|
||||
var _objects = $('#' + $app.table_host.dom_id + ' tbody').find('[data-check-box]');
|
||||
let _objects = $('#' + $app.table_host.dom_id + ' tbody').find('[data-check-box]');
|
||||
if ($(this).is(':checked')) {
|
||||
$.each(_objects, function (i, _obj) {
|
||||
$(_obj).prop('checked', true);
|
||||
|
@ -227,8 +227,8 @@ $app.on_table_host_cell_created = function (tbl, row_id, col_key, cell_obj) {
|
|||
} else if (col_key === 'action') {
|
||||
// 绑定系统选择框事件
|
||||
cell_obj.find('[data-action]').click(function () {
|
||||
var host = $app.table_host.get_row(row_id);
|
||||
var action = $(this).attr('data-action');
|
||||
let host = $app.table_host.get_row(row_id);
|
||||
let action = $(this).attr('data-action');
|
||||
if (action === 'edit') {
|
||||
$app.dlg_edit_host.show_edit(row_id);
|
||||
} else if (action === 'account') {
|
||||
|
@ -265,12 +265,12 @@ $app.on_table_host_cell_created = function (tbl, row_id, col_key, cell_obj) {
|
|||
$app.on_table_host_render_created = function (render) {
|
||||
|
||||
render.filter_state = function (header, title, col) {
|
||||
var _ret = ['<div class="tp-table-filter tp-table-filter-' + col.cell_align + '">'];
|
||||
let _ret = ['<div class="tp-table-filter tp-table-filter-' + col.cell_align + '">'];
|
||||
_ret.push('<div class="tp-table-filter-inner">');
|
||||
_ret.push('<div class="search-title">' + title + '</div>');
|
||||
|
||||
// 表格内嵌过滤器的DOM实体在这时生成
|
||||
var filter_ctrl = header._table_ctrl.get_filter_ctrl('state');
|
||||
let filter_ctrl = header._table_ctrl.get_filter_ctrl('state');
|
||||
_ret.push(filter_ctrl.render());
|
||||
|
||||
_ret.push('</div></div>');
|
||||
|
@ -279,12 +279,12 @@ $app.on_table_host_render_created = function (render) {
|
|||
};
|
||||
|
||||
render.filter_search = function (header, title, col) {
|
||||
var _ret = ['<div class="tp-table-filter tp-table-filter-input">'];
|
||||
let _ret = ['<div class="tp-table-filter tp-table-filter-input">'];
|
||||
_ret.push('<div class="tp-table-filter-inner">');
|
||||
_ret.push('<div class="search-title">' + title + '</div>');
|
||||
|
||||
// 表格内嵌过滤器的DOM实体在这时生成
|
||||
var filter_ctrl = header._table_ctrl.get_filter_ctrl('search');
|
||||
let filter_ctrl = header._table_ctrl.get_filter_ctrl('search');
|
||||
_ret.push(filter_ctrl.render());
|
||||
|
||||
_ret.push('</div></div>');
|
||||
|
@ -297,7 +297,7 @@ $app.on_table_host_render_created = function (render) {
|
|||
};
|
||||
|
||||
render.host_info = function (row_id, fields) {
|
||||
var title, sub_title;
|
||||
let title, sub_title;
|
||||
|
||||
title = fields.name;
|
||||
sub_title = fields.ip;
|
||||
|
@ -306,7 +306,7 @@ $app.on_table_host_render_created = function (render) {
|
|||
title = fields.ip;
|
||||
}
|
||||
|
||||
var desc = [];
|
||||
let desc = [];
|
||||
if (fields.desc.length > 0) {
|
||||
desc.push(fields.desc.replace(/\r/ig, "").replace(/\n/ig, "<br/>"));
|
||||
}
|
||||
|
@ -314,7 +314,7 @@ $app.on_table_host_render_created = function (render) {
|
|||
sub_title += ',由 ' + fields.router_ip + ':' + fields.router_port + ' 路由';
|
||||
}
|
||||
|
||||
var ret = [];
|
||||
let ret = [];
|
||||
// ret.push('<div><span class="host-name" href="javascript:;">' + title + '</span>');
|
||||
// if (desc.length > 0) {
|
||||
// ret.push('<a class="host-id-desc" data-toggle="popover" data-placement="right"');
|
||||
|
@ -347,9 +347,9 @@ $app.on_table_host_render_created = function (render) {
|
|||
};
|
||||
|
||||
render.host_state = function (row_id, fields) {
|
||||
var _style, _state;
|
||||
let i, _style, _state;
|
||||
|
||||
for (var i = 0; i < $app.obj_states.length; ++i) {
|
||||
for (i = 0; i < $app.obj_states.length; ++i) {
|
||||
if ($app.obj_states[i].id === fields.state) {
|
||||
_style = $app.obj_states[i].style;
|
||||
_state = $app.obj_states[i].name;
|
||||
|
@ -365,7 +365,7 @@ $app.on_table_host_render_created = function (render) {
|
|||
};
|
||||
|
||||
render.host_alive = function (row_id, fields) {
|
||||
var _style, _alive;
|
||||
let _style, _alive;
|
||||
|
||||
if (fields.alive === -1) {
|
||||
_style = 'alive-unknown';
|
||||
|
@ -391,7 +391,7 @@ $app.on_table_host_render_created = function (render) {
|
|||
_alive = '正在检测';
|
||||
}
|
||||
|
||||
var ret = [];
|
||||
let ret = [];
|
||||
|
||||
ret.push('<div><a class="alive ' + _style + '" data-toggle="popover" data-placement="left"');
|
||||
ret.push(' data-html="true"');
|
||||
|
@ -403,7 +403,7 @@ $app.on_table_host_render_created = function (render) {
|
|||
};
|
||||
|
||||
render.make_host_action_btn = function (row_id, fields) {
|
||||
var h = [];
|
||||
let h = [];
|
||||
h.push('<div class="btn-group btn-group-sm">');
|
||||
h.push('<button type="button" class="btn btn-no-border dropdown-toggle" data-toggle="dropdown">');
|
||||
h.push('<span data-selected-action>操作</span> <i class="fa fa-caret-right"></i></button>');
|
||||
|
@ -433,7 +433,7 @@ $app.on_table_host_header_created = function (header) {
|
|||
});
|
||||
|
||||
// TODO: 当过滤器不是默认值时,让“重置过滤器按钮”有呼吸效果,避免用户混淆 - 实验性质
|
||||
// var t1 = function(){
|
||||
// let t1 = function(){
|
||||
// $app.dom.btn_table_host_reset_filter.fadeTo(1000, 1.0, function(){
|
||||
// $app.dom.btn_table_host_reset_filter.fadeTo(1000, 0.2, t1);
|
||||
// });
|
||||
|
@ -447,8 +447,8 @@ $app.on_table_host_header_created = function (header) {
|
|||
};
|
||||
|
||||
$app.check_host_all_selected = function (cb_stack) {
|
||||
var _all_checked = true;
|
||||
var _objs = $('#' + $app.table_host.dom_id + ' tbody').find('[data-check-box]');
|
||||
let _all_checked = true;
|
||||
let _objs = $('#' + $app.table_host.dom_id + ' tbody').find('[data-check-box]');
|
||||
if (_objs.length === 0) {
|
||||
_all_checked = false;
|
||||
} else {
|
||||
|
@ -472,15 +472,15 @@ $app.check_host_all_selected = function (cb_stack) {
|
|||
|
||||
$app.on_btn_select_file_click = function () {
|
||||
|
||||
var html = '<input id="file-selector" type="file" name="csvfile" accept=".csv,text/csv,text/comma-separated-values" class="hidden" value="" style="display: none;"/>';
|
||||
let html = '<input id="file-selector" type="file" name="csvfile" accept=".csv,text/csv,text/comma-separated-values" class="hidden" value="" style="display: none;"/>';
|
||||
$('body').after($(html));
|
||||
var btn_file_selector = $("#file-selector");
|
||||
let btn_file_selector = $("#file-selector");
|
||||
|
||||
btn_file_selector.change(function () {
|
||||
$app.dom.upload_file_message.hide();
|
||||
// var dom_file_name = $('#upload-file-name');
|
||||
// let dom_file_name = $('#upload-file-name');
|
||||
|
||||
var file = null;
|
||||
let file = null;
|
||||
if (btn_file_selector[0].files && btn_file_selector[0].files[0]) {
|
||||
file = btn_file_selector[0].files[0];
|
||||
} else if (btn_file_selector[0].files && btn_file_selector[0].files.item(0)) {
|
||||
|
@ -492,7 +492,7 @@ $app.on_btn_select_file_click = function () {
|
|||
return;
|
||||
}
|
||||
|
||||
var _ext = file.name.substring(file.name.lastIndexOf('.')).toLocaleLowerCase();
|
||||
let _ext = file.name.substring(file.name.lastIndexOf('.')).toLocaleLowerCase();
|
||||
if (_ext !== '.csv') {
|
||||
$app.dom.upload_file_info.html('抱歉,仅支持导入 csv 格式的文件!');
|
||||
return;
|
||||
|
@ -503,7 +503,7 @@ $app.on_btn_select_file_click = function () {
|
|||
return;
|
||||
}
|
||||
|
||||
var fileInfo = '';
|
||||
let fileInfo = '';
|
||||
fileInfo += file.name;
|
||||
fileInfo += '<br/>';
|
||||
fileInfo += tp_size2str(file.size, 2);
|
||||
|
@ -526,7 +526,7 @@ $app.on_btn_do_upload_click = function () {
|
|||
.show();
|
||||
|
||||
|
||||
var param = {};
|
||||
let param = {};
|
||||
$.ajaxFileUpload({
|
||||
url: "/asset/upload-import",// 需要链接到服务器地址
|
||||
fileElementId: "file-selector", // 文件选择框的id属性
|
||||
|
@ -538,7 +538,7 @@ $app.on_btn_do_upload_click = function () {
|
|||
console.log(data);
|
||||
$('#file-selector').remove();
|
||||
|
||||
var ret = JSON.parse(data);
|
||||
let ret = JSON.parse(data);
|
||||
console.log(ret);
|
||||
|
||||
if (ret.code === TPE_OK) {
|
||||
|
@ -549,10 +549,10 @@ $app.on_btn_do_upload_click = function () {
|
|||
|
||||
$app.table_host.load_data();
|
||||
} else {
|
||||
var err_msg = ['<i class="far fa-times-circle fa-fw"></i> 资产导入失败:' + ret.message];
|
||||
let err_msg = ['<i class="far fa-times-circle fa-fw"></i> 资产导入失败:' + ret.message];
|
||||
if (!_.isUndefined(ret.data)) {
|
||||
err_msg.push('<div style="max-height:280px;overflow:auto;margin-left:20px;">');
|
||||
var err_lines = [];
|
||||
let err_lines = [];
|
||||
$.each(ret.data, function (i, item) {
|
||||
err_lines.push('第' + item.line + '行:' + item.error);
|
||||
});
|
||||
|
@ -580,11 +580,11 @@ $app.show_user_info = function (row_id) {
|
|||
};
|
||||
|
||||
$app.get_selected_host = function (tbl) {
|
||||
var items = [];
|
||||
var _objs = $('#' + $app.table_host.dom_id + ' tbody tr td input[data-check-box]');
|
||||
let items = [];
|
||||
let _objs = $('#' + $app.table_host.dom_id + ' tbody tr td input[data-check-box]');
|
||||
$.each(_objs, function (i, _obj) {
|
||||
if ($(_obj).is(':checked')) {
|
||||
var _row_data = tbl.get_row(_obj);
|
||||
let _row_data = tbl.get_row(_obj);
|
||||
// _all_checked = false;
|
||||
items.push(_row_data.id);
|
||||
}
|
||||
|
@ -609,7 +609,7 @@ $app._lock_hosts = function (host_ids) {
|
|||
};
|
||||
|
||||
$app.on_btn_lock_host_click = function () {
|
||||
var items = $app.get_selected_host($app.table_host);
|
||||
let items = $app.get_selected_host($app.table_host);
|
||||
if (items.length === 0) {
|
||||
$tp.notify_error('请选择要禁用的主机!');
|
||||
return;
|
||||
|
@ -635,7 +635,7 @@ $app._unlock_hosts = function (host_ids) {
|
|||
};
|
||||
|
||||
$app.on_btn_unlock_host_click = function () {
|
||||
var items = $app.get_selected_host($app.table_host);
|
||||
let items = $app.get_selected_host($app.table_host);
|
||||
if (items.length === 0) {
|
||||
$tp.notify_error('请选择要解禁的主机!');
|
||||
return;
|
||||
|
@ -645,7 +645,7 @@ $app.on_btn_unlock_host_click = function () {
|
|||
};
|
||||
|
||||
$app._remove_hosts = function (host_ids) {
|
||||
var _fn_sure = function (cb_stack) {
|
||||
let _fn_sure = function (cb_stack) {
|
||||
$tp.ajax_post_json('/asset/update-hosts', {action: 'remove', hosts: host_ids},
|
||||
function (ret) {
|
||||
if (ret.code === TPE_OK) {
|
||||
|
@ -665,7 +665,7 @@ $app._remove_hosts = function (host_ids) {
|
|||
);
|
||||
};
|
||||
|
||||
var cb_stack = CALLBACK_STACK.create();
|
||||
let cb_stack = CALLBACK_STACK.create();
|
||||
$tp.dlg_confirm(cb_stack, {
|
||||
msg: '<div class="alert alert-danger"><p><strong>注意:删除操作不可恢复!!</strong></p><p>删除主机将同时删除与之相关的账号,并将主机和账号从所在分组中移除,同时删除所有相关授权!</p></div><p>如果您希望临时禁止登录指定主机,可将其“禁用”!</p><p>您确定要移除选定的' + host_ids.length + '个主机吗?</p>',
|
||||
fn_yes: _fn_sure
|
||||
|
@ -673,7 +673,7 @@ $app._remove_hosts = function (host_ids) {
|
|||
};
|
||||
|
||||
$app.on_btn_remove_host_click = function () {
|
||||
var items = $app.get_selected_host($app.table_host);
|
||||
let items = $app.get_selected_host($app.table_host);
|
||||
if (items.length === 0) {
|
||||
$tp.notify_error('请选择要删除的主机!');
|
||||
return;
|
||||
|
@ -683,7 +683,7 @@ $app.on_btn_remove_host_click = function () {
|
|||
};
|
||||
|
||||
$app.create_dlg_edit_host = function () {
|
||||
var dlg = {};
|
||||
let dlg = {};
|
||||
dlg.dom_id = 'dlg-edit-host';
|
||||
dlg.field_id = -1; // 主机id(仅编辑模式)
|
||||
// dlg.field_type = -1;
|
||||
|
@ -716,7 +716,7 @@ $app.create_dlg_edit_host = function () {
|
|||
};
|
||||
|
||||
dlg.init = function (cb_stack) {
|
||||
var html = [];
|
||||
let html = [];
|
||||
// // 创建类型选择框
|
||||
// html.push('<button type="button" class="btn btn-sm dropdown-toggle" data-toggle="dropdown">');
|
||||
// html.push('<span data-selected-type>选择主机类型</span> <i class="fa fa-caret-right"></i></button>');
|
||||
|
@ -730,10 +730,10 @@ $app.create_dlg_edit_host = function () {
|
|||
//
|
||||
// // 绑定类型选择框事件
|
||||
// $('#' + dlg.dom_id + ' li a[data-type-selector]').click(function () {
|
||||
// var select = parseInt($(this).attr('data-type-selector'));
|
||||
// let select = parseInt($(this).attr('data-type-selector'));
|
||||
// if (dlg.field_type === select)
|
||||
// return;
|
||||
// var name = $app.id2name($app.host_types, select);
|
||||
// let name = $app.id2name($app.host_types, select);
|
||||
// if (_.isUndefined(name)) {
|
||||
// name = '选择主机类型角色';
|
||||
// dlg.field_type = -1;
|
||||
|
@ -772,9 +772,9 @@ $app.create_dlg_edit_host = function () {
|
|||
};
|
||||
|
||||
dlg.init_fields = function (host) {
|
||||
// var type_name = '选择主机类型';
|
||||
// let type_name = '选择主机类型';
|
||||
// dlg.field_type = -1;
|
||||
// var os_name = '选择操作系统';
|
||||
// let os_name = '选择操作系统';
|
||||
dlg.field_id = -1;
|
||||
dlg.field_os_type = -1;
|
||||
|
||||
|
@ -792,7 +792,7 @@ $app.create_dlg_edit_host = function () {
|
|||
dlg.field_id = host.id;
|
||||
dlg.dom.dlg_title.html('编辑主机:');
|
||||
|
||||
var _name = $app.id2name($app.host_os_type, host.os_type);
|
||||
let _name = $app.id2name($app.host_os_type, host.os_type);
|
||||
if (!_.isUndefined(_name)) {
|
||||
// os_name = _name;
|
||||
}
|
||||
|
@ -831,7 +831,7 @@ $app.create_dlg_edit_host = function () {
|
|||
};
|
||||
|
||||
dlg.show_edit = function (row_id) {
|
||||
var host = $app.table_host.get_row(row_id);
|
||||
let host = $app.table_host.get_row(row_id);
|
||||
dlg.init_fields(host);
|
||||
dlg.dom.dialog.modal({backdrop: 'static'});
|
||||
};
|
||||
|
@ -909,14 +909,14 @@ $app.create_dlg_edit_host = function () {
|
|||
if (!dlg.check_input())
|
||||
return;
|
||||
|
||||
var action = (dlg.field_id === -1) ? '添加' : '更新';
|
||||
let action = (dlg.field_id === -1) ? '添加' : '更新';
|
||||
|
||||
// var router_addr = '';
|
||||
// let router_addr = '';
|
||||
// if (dlg.field_conn_mode === 1) {
|
||||
// router_addr = dlg.field_router_ip + ':' + dlg.field_router_port;
|
||||
// }
|
||||
|
||||
var args = {
|
||||
let args = {
|
||||
id: dlg.field_id,
|
||||
os_type: dlg.field_os_type,
|
||||
ip: dlg.field_ip,
|
||||
|
@ -948,7 +948,7 @@ $app.create_dlg_edit_host = function () {
|
|||
};
|
||||
|
||||
$app.create_dlg_accounts = function () {
|
||||
var dlg = {};
|
||||
let dlg = {};
|
||||
dlg.dom_id = 'dlg-accounts';
|
||||
dlg.host_row_id = -1;
|
||||
dlg.host = null;
|
||||
|
@ -977,7 +977,7 @@ $app.create_dlg_accounts = function () {
|
|||
// 账号列表表格
|
||||
//-------------------------------
|
||||
|
||||
var table_acc_options = {
|
||||
let table_acc_options = {
|
||||
dom_id: 'table-acc',
|
||||
data_source: {
|
||||
type: 'none'
|
||||
|
@ -1069,7 +1069,7 @@ $app.create_dlg_accounts = function () {
|
|||
});
|
||||
|
||||
dlg.dom.chkbox_acc_select_all.click(function () {
|
||||
var _objects = $('#' + $app.table_acc.dom_id + ' tbody').find('[data-check-box]');
|
||||
let _objects = $('#' + $app.table_acc.dom_id + ' tbody').find('[data-check-box]');
|
||||
if ($(this).is(':checked')) {
|
||||
$.each(_objects, function (i, _obj) {
|
||||
$(_obj).prop('checked', true);
|
||||
|
@ -1085,11 +1085,11 @@ $app.create_dlg_accounts = function () {
|
|||
};
|
||||
|
||||
dlg.get_selected_acc = function (tbl) {
|
||||
var items = [];
|
||||
var _objs = $('#' + tbl.dom_id + ' tbody tr td input[data-check-box]');
|
||||
let items = [];
|
||||
let _objs = $('#' + tbl.dom_id + ' tbody tr td input[data-check-box]');
|
||||
$.each(_objs, function (i, _obj) {
|
||||
if ($(_obj).is(':checked')) {
|
||||
var _row_data = tbl.get_row(_obj);
|
||||
let _row_data = tbl.get_row(_obj);
|
||||
items.push(_row_data.id);
|
||||
}
|
||||
});
|
||||
|
@ -1116,7 +1116,7 @@ $app.create_dlg_accounts = function () {
|
|||
};
|
||||
|
||||
dlg.on_btn_lock_acc_click = function () {
|
||||
var items = dlg.get_selected_acc($app.table_acc);
|
||||
let items = dlg.get_selected_acc($app.table_acc);
|
||||
if (items.length === 0) {
|
||||
$tp.notify_error('请选择要禁用的账号!');
|
||||
return;
|
||||
|
@ -1146,7 +1146,7 @@ $app.create_dlg_accounts = function () {
|
|||
};
|
||||
|
||||
dlg.on_btn_unlock_acc_click = function () {
|
||||
var items = dlg.get_selected_acc($app.table_acc);
|
||||
let items = dlg.get_selected_acc($app.table_acc);
|
||||
if (items.length === 0) {
|
||||
$tp.notify_error('请选择要解禁的账号!');
|
||||
return;
|
||||
|
@ -1156,7 +1156,7 @@ $app.create_dlg_accounts = function () {
|
|||
};
|
||||
|
||||
dlg._remove_acc = function (acc_ids) {
|
||||
var _fn_sure = function (cb_stack) {
|
||||
let _fn_sure = function (cb_stack) {
|
||||
$tp.ajax_post_json('/asset/update-accounts', {action: 'remove', host_id: dlg.host.id, accounts: acc_ids},
|
||||
function (ret) {
|
||||
if (ret.code === TPE_OK) {
|
||||
|
@ -1166,7 +1166,7 @@ $app.create_dlg_accounts = function () {
|
|||
.exec();
|
||||
$tp.notify_success('删除主机操作成功!');
|
||||
|
||||
var update_args = {
|
||||
let update_args = {
|
||||
acc_count: dlg.host.acc_count - acc_ids.length
|
||||
};
|
||||
$app.table_host.update_row(dlg.host_row_id, update_args);
|
||||
|
@ -1184,7 +1184,7 @@ $app.create_dlg_accounts = function () {
|
|||
);
|
||||
};
|
||||
|
||||
var cb_stack = CALLBACK_STACK.create();
|
||||
let cb_stack = CALLBACK_STACK.create();
|
||||
$tp.dlg_confirm(cb_stack, {
|
||||
msg: '<div class="alert alert-danger"><p><strong>注意:删除操作不可恢复!!</strong></p></div><p>如果您希望临时禁止以指定账号登录远程主机,可将其“禁用”!</p><p>您确定要移除选定的' + acc_ids.length + '个账号吗?</p>',
|
||||
fn_yes: _fn_sure
|
||||
|
@ -1192,7 +1192,7 @@ $app.create_dlg_accounts = function () {
|
|||
};
|
||||
|
||||
dlg.on_btn_remove_acc_click = function () {
|
||||
var items = dlg.get_selected_acc($app.table_acc);
|
||||
let items = dlg.get_selected_acc($app.table_acc);
|
||||
if (items.length === 0) {
|
||||
$tp.notify_error('请选择要删除的账号!');
|
||||
return;
|
||||
|
@ -1241,9 +1241,9 @@ $app.create_dlg_accounts = function () {
|
|||
// 绑定系统选择框事件
|
||||
cell_obj.find('[data-action]').click(function () {
|
||||
|
||||
var action = $(this).attr('data-action');
|
||||
var acc_id = $(this).attr('data-id');
|
||||
var acc = tbl.get_row(row_id);
|
||||
let action = $(this).attr('data-action');
|
||||
let acc_id = $(this).attr('data-id');
|
||||
let acc = tbl.get_row(row_id);
|
||||
|
||||
if (action === 'edit') {
|
||||
$app.dlg_edit_account.show_edit(dlg.host_row_id, acc);
|
||||
|
@ -1261,12 +1261,12 @@ $app.create_dlg_accounts = function () {
|
|||
dlg.on_table_acc_render_created = function (render) {
|
||||
|
||||
// render.filter_state = function (header, title, col) {
|
||||
// var _ret = ['<div class="tp-table-filter tp-table-filter-' + col.cell_align + '">'];
|
||||
// let _ret = ['<div class="tp-table-filter tp-table-filter-' + col.cell_align + '">'];
|
||||
// _ret.push('<div class="tp-table-filter-inner">');
|
||||
// _ret.push('<div class="search-title">' + title + '</div>');
|
||||
//
|
||||
// // 表格内嵌过滤器的DOM实体在这时生成
|
||||
// var filter_ctrl = header._table_ctrl.get_filter_ctrl('state');
|
||||
// let filter_ctrl = header._table_ctrl.get_filter_ctrl('state');
|
||||
// _ret.push(filter_ctrl.render());
|
||||
//
|
||||
// _ret.push('</div></div>');
|
||||
|
@ -1275,12 +1275,12 @@ $app.create_dlg_accounts = function () {
|
|||
// };
|
||||
//
|
||||
// render.filter_search = function (header, title, col) {
|
||||
// var _ret = ['<div class="tp-table-filter tp-table-filter-input">'];
|
||||
// let _ret = ['<div class="tp-table-filter tp-table-filter-input">'];
|
||||
// _ret.push('<div class="tp-table-filter-inner">');
|
||||
// _ret.push('<div class="search-title">' + title + '</div>');
|
||||
//
|
||||
// // 表格内嵌过滤器的DOM实体在这时生成
|
||||
// var filter_ctrl = header._table_ctrl.get_filter_ctrl('search');
|
||||
// let filter_ctrl = header._table_ctrl.get_filter_ctrl('search');
|
||||
// _ret.push(filter_ctrl.render());
|
||||
//
|
||||
// _ret.push('</div></div>');
|
||||
|
@ -1294,7 +1294,7 @@ $app.create_dlg_accounts = function () {
|
|||
|
||||
render.acc_info = function (row_id, fields) {
|
||||
return fields.username;
|
||||
// var ret = [];
|
||||
// let ret = [];
|
||||
//
|
||||
// ret.push('<span class="user-surname">' + fields.username + '@' + fields.host_ip + '</span>');
|
||||
// if (fields.router_ip.length > 0)
|
||||
|
@ -1330,9 +1330,9 @@ $app.create_dlg_accounts = function () {
|
|||
};
|
||||
|
||||
render.acc_state = function (row_id, fields) {
|
||||
var _style, _state;
|
||||
let i, _style, _state;
|
||||
|
||||
for (var i = 0; i < $app.obj_states.length; ++i) {
|
||||
for (i = 0; i < $app.obj_states.length; ++i) {
|
||||
if ($app.obj_states[i].id === fields.state) {
|
||||
_style = $app.obj_states[i].style;
|
||||
_state = $app.obj_states[i].name;
|
||||
|
@ -1348,7 +1348,7 @@ $app.create_dlg_accounts = function () {
|
|||
};
|
||||
|
||||
render.make_host_action_btn = function (row_id, fields) {
|
||||
// var h = [];
|
||||
// let h = [];
|
||||
// h.push('<div class="btn-group btn-group-sm">');
|
||||
// h.push('<button type="button" class="btn btn-no-border dropdown-toggle" data-toggle="dropdown">');
|
||||
// h.push('<span data-selected-action>操作</span> <i class="fa fa-caret-right"></i></button>');
|
||||
|
@ -1367,7 +1367,7 @@ $app.create_dlg_accounts = function () {
|
|||
// return h.join('');
|
||||
|
||||
|
||||
var ret = [];
|
||||
let ret = [];
|
||||
ret.push('<div class="btn-group btn-group-sm" role="group">');
|
||||
ret.push('<btn class="btn btn-primary" data-action="edit" data-id="' + fields.id + '"><i class="fa fa-edit"></i> 编辑</btn>');
|
||||
|
||||
|
@ -1398,8 +1398,8 @@ $app.create_dlg_accounts = function () {
|
|||
};
|
||||
|
||||
dlg.check_acc_all_selected = function (cb_stack) {
|
||||
var _all_checked = true;
|
||||
var _objs = $('#' + $app.table_acc.dom_id + ' tbody').find('[data-check-box]');
|
||||
let _all_checked = true;
|
||||
let _objs = $('#' + $app.table_acc.dom_id + ' tbody').find('[data-check-box]');
|
||||
if (_objs.length === 0) {
|
||||
_all_checked = false;
|
||||
} else {
|
||||
|
@ -1426,7 +1426,7 @@ $app.create_dlg_accounts = function () {
|
|||
};
|
||||
|
||||
$app.create_dlg_edit_account = function () {
|
||||
var dlg = {};
|
||||
let dlg = {};
|
||||
dlg.dom_id = 'dlg-edit-account';
|
||||
dlg.host_row_id = -1;
|
||||
dlg.host = null;
|
||||
|
@ -1460,6 +1460,8 @@ $app.create_dlg_edit_account = function () {
|
|||
prompt_password: $('#account-password-prompt'),
|
||||
btn_show_password: $('#btn-show-account-password'),
|
||||
btn_show_password_icon: $('#btn-show-account-password i'),
|
||||
btn_clear_password: $('#btn-clear-password'),
|
||||
block_clear_password: $('#block-clear-password'),
|
||||
btn_test: $('#btn-edit-account-test'),
|
||||
btn_save: $('#btn-edit-account-save')
|
||||
};
|
||||
|
@ -1481,6 +1483,24 @@ $app.create_dlg_edit_account = function () {
|
|||
}
|
||||
});
|
||||
|
||||
dlg.dom.btn_clear_password.click(function () {
|
||||
$tp.ajax_post_json('/asset/clear-account-password', {
|
||||
host_id: dlg.host.id,
|
||||
acc_id: dlg.field_id
|
||||
},
|
||||
function (ret) {
|
||||
if (ret.code === TPE_OK) {
|
||||
$tp.notify_success('远程账号预设密码清除成功!');
|
||||
} else {
|
||||
$tp.notify_error('远程账号预设密码清除失败:' + tp_error_msg(ret.code, ret.message));
|
||||
}
|
||||
},
|
||||
function () {
|
||||
$tp.notify_error('网络故障,远程账号预设密码清除失败!');
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
cb_stack.exec();
|
||||
};
|
||||
|
||||
|
@ -1492,6 +1512,7 @@ $app.create_dlg_edit_account = function () {
|
|||
dlg.account = null;
|
||||
dlg.field_id = -1;
|
||||
dlg.dom.dlg_title.html('添加远程账号');
|
||||
dlg.dom.block_clear_password.hide();
|
||||
|
||||
if (dlg.host.os_type === TP_OS_TYPE_LINUX) {
|
||||
dlg.dom.protocol_type.val(TP_PROTOCOL_TYPE_SSH);
|
||||
|
@ -1506,6 +1527,7 @@ $app.create_dlg_edit_account = function () {
|
|||
dlg.account = account;
|
||||
dlg.field_id = account.id;
|
||||
dlg.dom.dlg_title.html('编辑:' + account.username);
|
||||
dlg.dom.block_clear_password.show();
|
||||
|
||||
dlg.dom.username.val(account.username);
|
||||
|
||||
|
@ -1525,7 +1547,7 @@ $app.create_dlg_edit_account = function () {
|
|||
dlg.on_protocol_change = function () {
|
||||
dlg.field_protocol = parseInt(dlg.dom.protocol_type.val());
|
||||
|
||||
var html = [];
|
||||
let html = [];
|
||||
if (dlg.field_protocol === TP_PROTOCOL_TYPE_RDP) {
|
||||
dlg.dom.block_rdp_param.show();
|
||||
dlg.dom.block_ssh_param.hide();
|
||||
|
@ -1673,11 +1695,12 @@ $app.create_dlg_edit_account = function () {
|
|||
}
|
||||
|
||||
if (dlg.field_auth_type === TP_AUTH_TYPE_PASSWORD) {
|
||||
if (dlg.field_id === -1 && dlg.field_password.length === 0) {
|
||||
dlg.dom.password.focus();
|
||||
$tp.notify_error('请填写登录远程主机的密码!');
|
||||
return false;
|
||||
}
|
||||
// 可以不用设置密码,在远程登录时用户再手动填写。
|
||||
// if (dlg.field_id === -1 && dlg.field_password.length === 0) {
|
||||
// dlg.dom.password.focus();
|
||||
// $tp.notify_error('请填写登录远程主机的密码!');
|
||||
// return false;
|
||||
// }
|
||||
dlg.field_pri_key = '';
|
||||
} else if (dlg.field_auth_type === TP_AUTH_TYPE_PRIVATE_KEY) {
|
||||
if (dlg.field_id === -1 && dlg.field_pri_key.length === 0) {
|
||||
|
@ -1700,7 +1723,7 @@ $app.create_dlg_edit_account = function () {
|
|||
if (!dlg.check_input())
|
||||
return;
|
||||
|
||||
var action = (dlg.field_id === -1) ? '添加' : '更新';
|
||||
let action = (dlg.field_id === -1) ? '添加' : '更新';
|
||||
|
||||
// 如果id为-1表示创建,否则表示更新
|
||||
$tp.ajax_post_json('/asset/update-account', {
|
||||
|
@ -1726,7 +1749,7 @@ $app.create_dlg_edit_account = function () {
|
|||
|
||||
if (dlg.field_id === -1) {
|
||||
// 新建账号成功了,更新界面上对应主机的账号数
|
||||
var update_args = {
|
||||
let update_args = {
|
||||
acc_count: dlg.host.acc_count + 1
|
||||
};
|
||||
$app.table_host.update_row(dlg.host_row_id, update_args);
|
||||
|
@ -1750,6 +1773,8 @@ $app.create_dlg_edit_account = function () {
|
|||
if (!dlg.check_input())
|
||||
return;
|
||||
|
||||
let is_interactive = (dlg.field_password.length === 0);
|
||||
|
||||
$assist.do_teleport(
|
||||
{
|
||||
mode: 0,
|
||||
|
@ -1764,7 +1789,8 @@ $app.create_dlg_edit_account = function () {
|
|||
password: dlg.field_password,
|
||||
pri_key: dlg.field_pri_key,
|
||||
username_prompt: dlg.field_prompt_username,
|
||||
password_prompt: dlg.field_prompt_password
|
||||
password_prompt: dlg.field_prompt_password,
|
||||
is_interactive: is_interactive
|
||||
},
|
||||
function () {
|
||||
// func_success
|
||||
|
|
|
@ -4,12 +4,10 @@ $app.on_init = function (cb_stack) {
|
|||
$app.dom = {
|
||||
btn_sel_group: $('#btn-sel-group button')
|
||||
, btn_refresh_host: $('#btn-refresh-host')
|
||||
// , group_list_for_sel: $('#btn-sel-group ul')
|
||||
// , group_selected: $('#group-selected')
|
||||
};
|
||||
|
||||
// console.log($app.options);
|
||||
if(!$app.options.core_cfg.detected) {
|
||||
if (!$app.options.core_cfg.detected) {
|
||||
$tp.notify_error('核心服务未启动,无法进行远程连接!');
|
||||
cb_stack.exec();
|
||||
return;
|
||||
|
@ -27,17 +25,10 @@ $app.on_init = function (cb_stack) {
|
|||
//===================================
|
||||
$app.create_controls = function (cb_stack) {
|
||||
|
||||
// var html = [];
|
||||
// $.each($app.options.host_groups, function (i, item) {
|
||||
// html.push('<li><a href="javascript:;" data-tp-selector="' + item.id + '" data-name="' + item.name + '"><i class="fa fa-caret-right fa-fw"></i> ' + item.name + '</a></li>');
|
||||
// });
|
||||
// $app.dom.group_list_for_sel.append($(html.join('')));
|
||||
//
|
||||
|
||||
//-------------------------------
|
||||
// 资产列表表格
|
||||
//-------------------------------
|
||||
var table_host_options = {
|
||||
let table_host_options = {
|
||||
dom_id: 'table-host',
|
||||
data_source: {
|
||||
type: 'ajax-post',
|
||||
|
@ -130,13 +121,14 @@ $app.create_controls = function (cb_stack) {
|
|||
$app.on_table_host_cell_created = function (tbl, row_id, col_key, cell_obj) {
|
||||
|
||||
if (col_key === 'action') {
|
||||
|
||||
// 绑定系统选择框事件
|
||||
cell_obj.find('[data-action]').click(function (e) {
|
||||
var action = $(this).attr('data-action');
|
||||
var protocol_sub_type = $(this).attr('data-sub-protocol');
|
||||
var uni_id = $(this).attr('data-id');
|
||||
var acc_id = parseInt($(this).attr('data-acc-id'));
|
||||
var host_id = parseInt($(this).attr('data-host-id'));
|
||||
let action = $(this).attr('data-action');
|
||||
let protocol_sub_type = $(this).attr('data-sub-protocol');
|
||||
let uni_id = $(this).attr('data-id');
|
||||
let acc_id = parseInt($(this).attr('data-acc-id'));
|
||||
let host_id = parseInt($(this).attr('data-host-id'));
|
||||
|
||||
if (action === 'rdp') {
|
||||
$app.connect_remote(uni_id, acc_id, host_id, TP_PROTOCOL_TYPE_RDP, TP_PROTOCOL_TYPE_RDP_DESKTOP);
|
||||
|
@ -146,6 +138,8 @@ $app.on_table_host_cell_created = function (tbl, row_id, col_key, cell_obj) {
|
|||
$app.connect_remote(uni_id, acc_id, host_id, TP_PROTOCOL_TYPE_SSH, protocol_sub_type);
|
||||
} else if (action === 'telnet') {
|
||||
$app.connect_remote(uni_id, acc_id, host_id, TP_PROTOCOL_TYPE_TELNET, TP_PROTOCOL_TYPE_TELNET_SHELL);
|
||||
} else if (action === 'get_config') {
|
||||
$app.get_remote_connection_config(acc_id, host_id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -154,12 +148,12 @@ $app.on_table_host_cell_created = function (tbl, row_id, col_key, cell_obj) {
|
|||
$app.on_table_host_render_created = function (render) {
|
||||
|
||||
render.filter_state = function (header, title, col) {
|
||||
var _ret = ['<div class="tp-table-filter tp-table-filter-' + col.cell_align + '">'];
|
||||
let _ret = ['<div class="tp-table-filter tp-table-filter-' + col.cell_align + '">'];
|
||||
_ret.push('<div class="tp-table-filter-inner">');
|
||||
_ret.push('<div class="search-title">' + title + '</div>');
|
||||
|
||||
// 表格内嵌过滤器的DOM实体在这时生成
|
||||
var filter_ctrl = header._table_ctrl.get_filter_ctrl('state');
|
||||
let filter_ctrl = header._table_ctrl.get_filter_ctrl('state');
|
||||
_ret.push(filter_ctrl.render());
|
||||
|
||||
_ret.push('</div></div>');
|
||||
|
@ -168,12 +162,12 @@ $app.on_table_host_render_created = function (render) {
|
|||
};
|
||||
|
||||
render.filter_search = function (header, title, col) {
|
||||
var _ret = ['<div class="tp-table-filter tp-table-filter-input">'];
|
||||
let _ret = ['<div class="tp-table-filter tp-table-filter-input">'];
|
||||
_ret.push('<div class="tp-table-filter-inner">');
|
||||
_ret.push('<div class="search-title">' + title + '</div>');
|
||||
|
||||
// 表格内嵌过滤器的DOM实体在这时生成
|
||||
var filter_ctrl = header._table_ctrl.get_filter_ctrl('search');
|
||||
let filter_ctrl = header._table_ctrl.get_filter_ctrl('search');
|
||||
_ret.push(filter_ctrl.render());
|
||||
|
||||
_ret.push('</div></div>');
|
||||
|
@ -182,7 +176,7 @@ $app.on_table_host_render_created = function (render) {
|
|||
};
|
||||
|
||||
render.host_info = function (row_id, fields) {
|
||||
var title, sub_title;
|
||||
let title, sub_title;
|
||||
|
||||
title = fields.h_name;
|
||||
sub_title = fields.ip;
|
||||
|
@ -193,77 +187,112 @@ $app.on_table_host_render_created = function (render) {
|
|||
|
||||
// title = fields.a_name + '@' + title;
|
||||
|
||||
var desc = [];
|
||||
// let desc = [];
|
||||
if (fields.router_ip.length > 0) {
|
||||
sub_title += ',由 ' + fields.router_ip + ':' + fields.router_port + ' 路由';
|
||||
}
|
||||
|
||||
var ret = [];
|
||||
if (desc.length > 0) {
|
||||
ret.push('<div><a class="host-name host-name-desc" data-toggle="popover" data-placement="right"');
|
||||
ret.push(' data-html="true"');
|
||||
ret.push(' data-content="' + desc.join('') + '"');
|
||||
ret.push('>' + title + '</a>');
|
||||
} else {
|
||||
ret.push('<div><span class="host-name">' + title + '</span>');
|
||||
}
|
||||
let ret = [];
|
||||
// if (desc.length > 0) {
|
||||
// ret.push('<div><a class="host-name host-name-desc" data-toggle="popover" data-placement="right"');
|
||||
// ret.push(' data-html="true"');
|
||||
// ret.push(' data-content="' + desc.join('') + '"');
|
||||
// ret.push('>' + title + '</a>');
|
||||
// } else {
|
||||
// ret.push('<div><span class="host-name">' + title + '</span>');
|
||||
// }
|
||||
|
||||
ret.push('<div><span class="host-name">' + title + '</span>');
|
||||
ret.push('</div><div class="host-ip" href="javascript:;" data-host-desc="' + sub_title + '">' + sub_title + '</div>');
|
||||
return ret.join('');
|
||||
};
|
||||
|
||||
render.account = function (row_id, fields) {
|
||||
var h = [];
|
||||
for (var i = 0; i < fields.accs.length; ++i) {
|
||||
var acc = fields.accs[i];
|
||||
h.push('<div class="remote-info-group" id =' + "account-id-" + acc.id + '"><ul>');
|
||||
let h = [];
|
||||
|
||||
// console.log('acc', fields);
|
||||
if (fields.h_state !== TP_STATE_NORMAL || (fields.gh_state !== TP_STATE_NORMAL && fields.gh_state !== 0)) {
|
||||
// 1. 主机已经被禁用,不显示相关账号。
|
||||
// 2. 主机所在分组已经被禁用,不显示相关账号。
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < fields.accs.length; ++i) {
|
||||
let acc = fields.accs[i];
|
||||
h.push('<div class="remote-info-group"><ul>');
|
||||
h.push('<li>' + acc.a_name + '</li>');
|
||||
h.push('</ul></div>');
|
||||
}
|
||||
|
||||
return h.join('');
|
||||
};
|
||||
render.action = function (row_id, fields) {
|
||||
// console.log(fields);
|
||||
var h = [];
|
||||
for (var i = 0; i < fields.accs.length; ++i) {
|
||||
var acc = fields.accs[i];
|
||||
var act_btn = [];
|
||||
// console.log('action', fields);
|
||||
|
||||
let is_disabled = false;
|
||||
let disable_msg = '';
|
||||
|
||||
if (fields.h_state !== TP_STATE_NORMAL) {
|
||||
is_disabled = true;
|
||||
disable_msg = '无可用远程连接,主机已被禁用';
|
||||
}
|
||||
if (fields.gh_state !== TP_STATE_NORMAL && fields.gh_state !== 0) {
|
||||
is_disabled = true;
|
||||
disable_msg = '无可用远程连接,主机所在分组已被禁用';
|
||||
}
|
||||
if (is_disabled) {
|
||||
let h = [];
|
||||
h.push('<div><div class="remote-action-group"><div class="btn-group btn-group-sm">');
|
||||
h.push('<button type="button" class="btn btn-disabled" disabled><i class="fa fa-ban fa-fw"></i> ');
|
||||
h.push(disable_msg);
|
||||
h.push('</button></div></div>');
|
||||
return h.join('');
|
||||
}
|
||||
|
||||
|
||||
let h = [];
|
||||
for (let i = 0; i < fields.accs.length; ++i) {
|
||||
let acc = fields.accs[i];
|
||||
let act_btn = [];
|
||||
|
||||
is_disabled = false;
|
||||
disable_msg = '';
|
||||
|
||||
var disabled = '';
|
||||
if (acc.a_state !== TP_STATE_NORMAL)
|
||||
disabled = '账号已禁用';
|
||||
if (disabled.length === 0 && (acc.policy_auth_type === TP_POLICY_AUTH_USER_gACC || acc.policy_auth_type === TP_POLICY_AUTH_gUSER_gACC) && acc.ga_state !== TP_STATE_NORMAL)
|
||||
disabled = '账号所在组已禁用';
|
||||
if (disabled.length === 0 && fields.h_state !== TP_STATE_NORMAL)
|
||||
disabled = '主机已禁用';
|
||||
if (disabled.length === 0 && (acc.policy_auth_type === TP_POLICY_AUTH_USER_gHOST || acc.policy_auth_type === TP_POLICY_AUTH_gUSER_gHOST) && fields.gh_state !== TP_STATE_NORMAL)
|
||||
disabled = '主机所在组已禁用';
|
||||
disable_msg = '账号已被禁用';
|
||||
if (disable_msg.length === 0 && (acc.policy_auth_type === TP_POLICY_AUTH_USER_gACC || acc.policy_auth_type === TP_POLICY_AUTH_gUSER_gACC) && acc.ga_state !== TP_STATE_NORMAL)
|
||||
disable_msg = '账号所在分组已被禁用';
|
||||
// if (disable_msg.length === 0 && fields.h_state !== TP_STATE_NORMAL)
|
||||
// disable_msg = '主机已被禁用';
|
||||
// if (disable_msg.length === 0 && (acc.policy_auth_type === TP_POLICY_AUTH_USER_gHOST || acc.policy_auth_type === TP_POLICY_AUTH_gUSER_gHOST) && fields.gh_state !== TP_STATE_NORMAL)
|
||||
// disable_msg = '主机所在组已被禁用';
|
||||
|
||||
if (disabled.length > 0) {
|
||||
act_btn.push('<li class="remote-action-state state-disabled">');
|
||||
act_btn.push('<i class="fa fa-ban fa-fw"></i> ' + disabled);
|
||||
act_btn.push('</li>');
|
||||
} else {
|
||||
if (acc.protocol_type === TP_PROTOCOL_TYPE_RDP) {
|
||||
if (disable_msg.length > 0)
|
||||
is_disabled = true;
|
||||
|
||||
if (acc.protocol_type === TP_PROTOCOL_TYPE_RDP) {
|
||||
if (!is_disabled) {
|
||||
if (!$app.options.core_cfg.rdp.enable) {
|
||||
act_btn.push('<li class="remote-action-state state-disabled">');
|
||||
act_btn.push('<i class="fa fa-ban fa-fw"></i> RDP协议未启用');
|
||||
act_btn.push('</li>');
|
||||
is_disabled = true;
|
||||
disable_msg = 'RDP协议未启用';
|
||||
} else {
|
||||
if ((acc.policy_.flag_rdp & TP_FLAG_RDP_DESKTOP) !== 0) {
|
||||
act_btn.push('<div class="btn-group btn-group-sm">');
|
||||
act_btn.push('<button type="button" class="btn btn-primary" data-action="rdp" data-id="' + acc.uni_id + '" data-acc-id="' + acc.a_id + '" data-host-id="' + acc.h_id + '" data-sub-protocol="' + TP_PROTOCOL_TYPE_RDP_DESKTOP + '"><i class="fa fa-desktop fa-fw"></i> RDP</button>');
|
||||
act_btn.push('<a href="javascript:;" class="btn btn-primary dropdown-toggle" data-action="rdp-option" data-id="' + acc.uni_id + '" data-acc-id="' + acc.a_id + '" data-host-id="' + acc.h_id + '" data-sub-protocol="' + TP_PROTOCOL_TYPE_RDP_DESKTOP + '">');
|
||||
act_btn.push('<button type="button" class="btn btn-primary dropdown-toggle" data-action="rdp-option" data-id="' + acc.uni_id + '" data-acc-id="' + acc.a_id + '" data-host-id="' + acc.h_id + '" data-sub-protocol="' + TP_PROTOCOL_TYPE_RDP_DESKTOP + '">');
|
||||
act_btn.push('<i class="fa fa-cog"></i>');
|
||||
act_btn.push('</a>');
|
||||
act_btn.push('</button>');
|
||||
act_btn.push('</div>');
|
||||
}
|
||||
}
|
||||
} else if (acc.protocol_type === TP_PROTOCOL_TYPE_SSH) {
|
||||
} else {
|
||||
disable_msg = 'RPD' + disable_msg;
|
||||
}
|
||||
} else if (acc.protocol_type === TP_PROTOCOL_TYPE_SSH) {
|
||||
if (!is_disabled) {
|
||||
if (!$app.options.core_cfg.ssh.enable) {
|
||||
act_btn.push('<li class="remote-action-state state-disabled">');
|
||||
act_btn.push('<i class="fa fa-ban fa-fw"></i> SSH协议未启用');
|
||||
act_btn.push('</li>');
|
||||
is_disabled = true;
|
||||
disable_msg = 'SSH协议未启用';
|
||||
} else {
|
||||
act_btn.push('<div class="btn-group btn-group-sm">');
|
||||
if ((acc.policy_.flag_ssh & TP_FLAG_SSH_SHELL) !== 0) {
|
||||
|
@ -275,23 +304,49 @@ $app.on_table_host_render_created = function (render) {
|
|||
}
|
||||
act_btn.push('</div>');
|
||||
}
|
||||
} else if (acc.protocol_type === TP_PROTOCOL_TYPE_TELNET) {
|
||||
} else {
|
||||
disable_msg = 'SSH' + disable_msg;
|
||||
}
|
||||
} else if (acc.protocol_type === TP_PROTOCOL_TYPE_TELNET) {
|
||||
if (!is_disabled) {
|
||||
if (!$app.options.core_cfg.telnet.enable) {
|
||||
act_btn.push('<li class="remote-action-state state-disabled">');
|
||||
act_btn.push('<i class="fa fa-ban fa-fw"></i> TELNET协议未启用');
|
||||
act_btn.push('</li>');
|
||||
is_disabled = true;
|
||||
disable_msg = 'TELNET协议未启用';
|
||||
} else {
|
||||
act_btn.push('<div class="btn-group btn-group-sm">');
|
||||
act_btn.push('<button type="button" class="btn btn-warning" data-action="telnet" data-id="' + acc.uni_id + '" data-acc-id="' + acc.a_id + '" data-host-id="' + acc.h_id + '" data-sub-protocol="' + TP_PROTOCOL_TYPE_TELNET_SHELL + '"><i class="far fa-keyboard fa-fw"></i> TELNET</button>');
|
||||
act_btn.push('</div>');
|
||||
}
|
||||
} else {
|
||||
disable_msg = 'TELNET' + disable_msg;
|
||||
}
|
||||
}
|
||||
|
||||
h.push('<div class="remote-action-group" id =' + "account-id-" + acc.id + '">');
|
||||
if (disable_msg.length > 0) {
|
||||
is_disabled = true;
|
||||
act_btn.push('<div class="btn-group btn-group-sm">');
|
||||
act_btn.push('<button type="button" class="btn btn-disabled" disabled><i class="fa fa-ban fa-fw"></i> ');
|
||||
act_btn.push(disable_msg);
|
||||
act_btn.push('</button>');
|
||||
act_btn.push('</div>');
|
||||
}
|
||||
|
||||
|
||||
h.push('<div>');
|
||||
h.push('<div class="remote-action-group">');
|
||||
h.push(act_btn.join(''));
|
||||
h.push('</div>');
|
||||
|
||||
if (!is_disabled) {
|
||||
h.push('<div class="remote-config">');
|
||||
h.push('<button type="button" class="btn btn-default" data-action="get_config" data-acc-id=' + acc.a_id + ' data-host-id=' + acc.h_id + '><i class="fa fa-key fa-fw"></i> 获取远程连接配置</button>');
|
||||
h.push('</div>');
|
||||
}
|
||||
|
||||
h.push('</div>');
|
||||
}
|
||||
|
||||
|
||||
return h.join('');
|
||||
};
|
||||
};
|
||||
|
@ -310,7 +365,7 @@ $app.on_table_host_header_created = function (header) {
|
|||
};
|
||||
|
||||
$app.create_dlg_rdp_options = function () {
|
||||
var dlg = {};
|
||||
let dlg = {};
|
||||
dlg.dom_id = 'dlg-rdp-options';
|
||||
dlg.uni_id = '';
|
||||
dlg.acc_id = 0;
|
||||
|
@ -345,10 +400,10 @@ $app.create_dlg_rdp_options = function () {
|
|||
dlg.dom.btn_connect.click(function () {
|
||||
dlg.hide();
|
||||
|
||||
var _size_obj = $('#' + dlg.dom_id + ' input[name="screen-size"]:checked');
|
||||
var _console = dlg.dom.console_mode.is(':checked');
|
||||
var _w = parseInt(_size_obj.attr('data-w'));
|
||||
var _h = parseInt(_size_obj.attr('data-h'));
|
||||
let _size_obj = $('#' + dlg.dom_id + ' input[name="screen-size"]:checked');
|
||||
let _console = dlg.dom.console_mode.is(':checked');
|
||||
let _w = parseInt(_size_obj.attr('data-w'));
|
||||
let _h = parseInt(_size_obj.attr('data-h'));
|
||||
|
||||
dlg.rdp_w = _w;
|
||||
dlg.rdp_h = _h;
|
||||
|
@ -358,7 +413,7 @@ $app.create_dlg_rdp_options = function () {
|
|||
$app.connect_remote(dlg.uni_id, dlg.acc_id, dlg.host_id, dlg.protocol_type, dlg.protocol_sub_type);
|
||||
});
|
||||
|
||||
var ops = Cookies.getJSON('rdp_options');
|
||||
let ops = Cookies.getJSON('rdp_options');
|
||||
dlg.rdp_w = 0;
|
||||
dlg.rdp_h = 0;
|
||||
dlg.rdp_console = false;
|
||||
|
@ -374,7 +429,7 @@ $app.create_dlg_rdp_options = function () {
|
|||
if (_.isUndefined(dlg.rdp_console))
|
||||
dlg.rdp_console = false;
|
||||
|
||||
var ss = [
|
||||
let ss = [
|
||||
{w: 800, h: 600},
|
||||
{w: 1024, h: 768},
|
||||
{w: 1280, h: 1024},
|
||||
|
@ -382,16 +437,16 @@ $app.create_dlg_rdp_options = function () {
|
|||
{w: 1440, h: 900}
|
||||
];
|
||||
|
||||
var h = [];
|
||||
let h = [];
|
||||
h.push('<div class="radio">');
|
||||
h.push('<div><label><input type="radio" name="screen-size" data-w="0" data-h="0"');
|
||||
if (dlg.rdp_w === 0 && dlg.rdp_h === 0)
|
||||
h.push(' checked');
|
||||
h.push('> 全屏</label></div>');
|
||||
|
||||
for (var i = 0; i < ss.length; ++i) {
|
||||
var _w = ss[i].w;
|
||||
var _h = ss[i].h;
|
||||
for (let i = 0; i < ss.length; ++i) {
|
||||
let _w = ss[i].w;
|
||||
let _h = ss[i].h;
|
||||
h.push('<div><label><input type="radio" name="screen-size" data-w="' + _w + '" data-h="' + _h + '"');
|
||||
if (dlg.rdp_w === _w && dlg.rdp_h === _h)
|
||||
h.push(' checked');
|
||||
|
@ -418,7 +473,7 @@ $app.create_dlg_rdp_options = function () {
|
|||
dlg.protocol_type = protocol_type;
|
||||
dlg.protocol_sub_type = protocol_sub_type;
|
||||
|
||||
var w = dlg.dom.dialog.width();
|
||||
let w = dlg.dom.dialog.width();
|
||||
x -= w / 3;
|
||||
y -= 12;
|
||||
dlg.dom.dialog.css({left: x, top: y});
|
||||
|
@ -432,36 +487,61 @@ $app.create_dlg_rdp_options = function () {
|
|||
return dlg;
|
||||
};
|
||||
|
||||
$app.get_remote_connection_config = function (acc_id, host_id) {
|
||||
console.log(acc_id, host_id);
|
||||
}
|
||||
|
||||
$app.connect_remote = function (uni_id, acc_id, host_id, protocol_type, protocol_sub_type) {
|
||||
|
||||
var args = {
|
||||
let args = {
|
||||
mode: 1,
|
||||
auth_id: uni_id,
|
||||
acc_id: acc_id,
|
||||
host_id: host_id,
|
||||
protocol_type: protocol_type,
|
||||
protocol_sub_type: protocol_sub_type,
|
||||
rdp_width: $app.dlg_rdp_options.rdp_w,
|
||||
rdp_height: $app.dlg_rdp_options.rdp_h,
|
||||
rdp_console: $app.dlg_rdp_options.rdp_console
|
||||
is_interactive: false,
|
||||
};
|
||||
|
||||
console.log('--s--', args);
|
||||
if (protocol_type === TP_PROTOCOL_TYPE_RDP) {
|
||||
args.extends({
|
||||
rdp_width: $app.dlg_rdp_options.rdp_w,
|
||||
rdp_height: $app.dlg_rdp_options.rdp_h,
|
||||
rdp_console: $app.dlg_rdp_options.rdp_console
|
||||
});
|
||||
}
|
||||
|
||||
if (uni_id === 'none')
|
||||
args.mode = 2;
|
||||
|
||||
$assist.do_teleport(
|
||||
args,
|
||||
function () {
|
||||
// func_success
|
||||
//$tp.notify_success('远程连接测试通过!');
|
||||
// 根据acc_id判断此远程账号是否有预设密码,如果没有,则需要设置interactive模式。
|
||||
$tp.ajax_post_json('/asset/get-account-interactive-mode',
|
||||
{acc_id: acc_id},
|
||||
function (ret) {
|
||||
console.log('ajax: /asset/get-account-interactive-mode', ret);
|
||||
if (ret.code === TPE_OK) {
|
||||
args.is_interactive = ret.data.is_interactive;
|
||||
console.log('--s--', args);
|
||||
|
||||
$assist.do_teleport(
|
||||
args,
|
||||
function () {
|
||||
// func_success
|
||||
//$tp.notify_success('远程连接测试通过!');
|
||||
},
|
||||
function (code, message) {
|
||||
if (code === TPE_NO_ASSIST)
|
||||
$assist.alert_assist_not_found(code);
|
||||
else
|
||||
$tp.notify_error('远程连接失败:' + tp_error_msg(code, message));
|
||||
}
|
||||
);
|
||||
|
||||
} else {
|
||||
$tp.notify_error('无法获取远程账号信息:' + tp_error_msg(ret.code, ret.message));
|
||||
}
|
||||
},
|
||||
function (code, message) {
|
||||
if (code === TPE_NO_ASSIST)
|
||||
$assist.alert_assist_not_found(code);
|
||||
else
|
||||
$tp.notify_error('远程连接失败:' + tp_error_msg(code, message));
|
||||
function () {
|
||||
$tp.notify_error('网络故障,无法获取远程账号信息!');
|
||||
}
|
||||
);
|
||||
};
|
||||
|
|
|
@ -822,7 +822,7 @@ $app.create_config_integration = function () {
|
|||
fields: {id: 'id'}
|
||||
},
|
||||
{
|
||||
title: '服务名称',
|
||||
title: '外部服务名称',
|
||||
key: 'name',
|
||||
width: 120,
|
||||
},
|
||||
|
@ -848,7 +848,7 @@ $app.create_config_integration = function () {
|
|||
title: '',
|
||||
key: 'action',
|
||||
align: 'center',
|
||||
width: 200,
|
||||
width: 150,
|
||||
render: 'make_action_btn',
|
||||
fields: {id: 'id'}
|
||||
}
|
||||
|
@ -920,7 +920,7 @@ $app.create_config_integration = function () {
|
|||
let ret = [];
|
||||
ret.push('<div class="btn-group btn-group-sm" role="group">');
|
||||
ret.push('<btn class="btn btn-primary" data-btn-edit="edit"><i class="fa fa-edit"></i> 编辑</btn>');
|
||||
ret.push('<btn class="btn btn-danger" data-btn-remove="' + fields.id + '"><i class="fas fa-trash-alt"></i> 删除</btn>');
|
||||
ret.push('<btn class="btn btn-danger" data-btn-remove="remove"><i class="fas fa-trash-alt"></i> 删除</btn>');
|
||||
ret.push('</div>');
|
||||
return ret.join('');
|
||||
};
|
||||
|
|
|
@ -532,7 +532,7 @@ $tp.create_table = function (options) {
|
|||
if (!_tbl.options.columns.hasOwnProperty(i))
|
||||
continue;
|
||||
let col = _tbl.options.columns[i];
|
||||
for (k in kv) {
|
||||
for (let k in kv) {
|
||||
if (!kv.hasOwnProperty(k))
|
||||
continue;
|
||||
|
||||
|
|
|
@ -412,7 +412,8 @@ $assist.do_teleport = function (args, func_success, func_error) {
|
|||
session_id: session_id,
|
||||
protocol_type: parseInt(args.protocol_type),
|
||||
protocol_sub_type: parseInt(args.protocol_sub_type),
|
||||
protocol_flag: parseInt(ret.data.protocol_flag)
|
||||
protocol_flag: parseInt(ret.data.protocol_flag),
|
||||
is_interactive: args.is_interactive
|
||||
};
|
||||
|
||||
if (args.protocol_type === TP_PROTOCOL_TYPE_RDP) {
|
||||
|
|
|
@ -19,7 +19,7 @@ html {
|
|||
|
||||
body {
|
||||
font-family: @font-family-normal;
|
||||
//font-size: @text-size-normal;
|
||||
font-size: @text-size-normal;
|
||||
background-color: @page-bg;
|
||||
color: @page-color;
|
||||
}
|
||||
|
|
|
@ -270,9 +270,9 @@
|
|||
color: #ac4e43;
|
||||
position: absolute;
|
||||
margin-left: -1.2em;
|
||||
margin-top: 1px;
|
||||
//margin-top: 1px;
|
||||
content: "\f069";
|
||||
font-size: 8px;
|
||||
//font-size: 8px;
|
||||
font-family: 'Font Awesome 5 Free';
|
||||
font-weight: 900;
|
||||
}
|
||||
|
@ -282,6 +282,11 @@
|
|||
color: #999;
|
||||
}
|
||||
.control-desc-sm {
|
||||
color: #999;
|
||||
padding-top: 7px;
|
||||
font-size: @text-size-small;
|
||||
}
|
||||
.control-desc-sm-input {
|
||||
color: #999;
|
||||
padding-top: 3px;
|
||||
font-size: @text-size-small;
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
@charset "utf-8";
|
||||
|
||||
.remote-action-group {
|
||||
display: inline-block;
|
||||
margin-bottom: 3px;
|
||||
height: 28px;
|
||||
|
||||
.btn-group-sm > .btn {
|
||||
margin: 0;
|
||||
padding: 6px 6px;
|
||||
//padding: 6px 6px;
|
||||
font-size: 12px;
|
||||
height: 28px;
|
||||
min-width: 80px;
|
||||
|
@ -14,6 +15,17 @@
|
|||
&.dropdown-toggle {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
&.btn-disabled {
|
||||
background-color: @color-bg-ignore;
|
||||
color: #aaa;
|
||||
//text-shadow: -1px -1px 1px #fff;
|
||||
|
||||
//& > i.fa {
|
||||
// color: #b53a2f;
|
||||
// text-shadow: none;
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
//& > ul {
|
||||
|
@ -59,6 +71,7 @@
|
|||
//width: 64px;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
height: 28px;
|
||||
|
||||
&.state-disabled {
|
||||
background-color: @color-bg-ignore;
|
||||
|
@ -136,6 +149,7 @@
|
|||
border-top-left-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
|
||||
//
|
||||
//&.remote-action-btn:first-child {
|
||||
// border: none;
|
||||
|
@ -149,6 +163,7 @@
|
|||
border-top-right-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
}
|
||||
|
||||
//
|
||||
//&.remote-action-btn:last-child {
|
||||
// border: none;
|
||||
|
@ -159,9 +174,24 @@
|
|||
//}
|
||||
|
||||
}
|
||||
|
||||
//}
|
||||
}
|
||||
|
||||
.remote-config {
|
||||
display: inline-block;
|
||||
margin-left: 20px;
|
||||
|
||||
button {
|
||||
margin: 0;
|
||||
//padding: 6px 6px;
|
||||
font-size: 12px;
|
||||
height: 28px;
|
||||
min-width: 80px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.remote-info-group {
|
||||
margin-bottom: 3px;
|
||||
height: 28px;
|
||||
|
@ -177,49 +207,52 @@
|
|||
position: relative;
|
||||
display: block;
|
||||
height: 28px;
|
||||
padding: 4px 5px;
|
||||
line-height: 28px;
|
||||
//padding: 4px 5px;
|
||||
|
||||
//background-color: #efefef;
|
||||
border-top: 1px solid #ccc;
|
||||
border-right: 1px solid #ccc;
|
||||
border-bottom: 1px solid #ccc;
|
||||
//border-top: 1px solid #ccc;
|
||||
//border-right: 1px solid #ccc;
|
||||
//border-bottom: 1px solid #ccc;
|
||||
border:none;
|
||||
|
||||
&.remote-action-btn {
|
||||
background: none;
|
||||
padding: 0;
|
||||
border: none;
|
||||
}
|
||||
//&.remote-action-btn {
|
||||
// background: none;
|
||||
// padding: 0;
|
||||
// border: none;
|
||||
//}
|
||||
//
|
||||
//&.remote-action-input {
|
||||
// background: none;
|
||||
// padding: 4px 0;
|
||||
//
|
||||
// select {
|
||||
// border: none;
|
||||
// }
|
||||
//}
|
||||
|
||||
&.remote-action-input {
|
||||
background: none;
|
||||
padding: 4px 0;
|
||||
//label {
|
||||
// padding: 0;
|
||||
// display: block;
|
||||
// float: left;
|
||||
// margin-top: 1px;
|
||||
// cursor: pointer;
|
||||
//}
|
||||
//
|
||||
//select {
|
||||
// margin-top: -3px;
|
||||
//}
|
||||
|
||||
select {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
label {
|
||||
padding: 0;
|
||||
display: block;
|
||||
float: left;
|
||||
margin-top: 1px;
|
||||
cursor: pointer;
|
||||
}
|
||||
select {
|
||||
margin-top: -3px;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
border-left: 1px solid #ccc;
|
||||
border-top-left-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-top-right-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
}
|
||||
//&:first-child {
|
||||
// border-left: 1px solid #ccc;
|
||||
// border-top-left-radius: 4px;
|
||||
// border-bottom-left-radius: 4px;
|
||||
//}
|
||||
//
|
||||
//&:last-child {
|
||||
// border-top-right-radius: 4px;
|
||||
// border-bottom-right-radius: 4px;
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -242,7 +275,8 @@
|
|||
|
||||
.title {
|
||||
background-color: #eee;
|
||||
padding: 3px 5px;
|
||||
padding: 5px 5px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.item {
|
||||
|
|
|
@ -585,9 +585,9 @@ body {
|
|||
// margin: 0 auto;
|
||||
//}
|
||||
//
|
||||
.form-group .input-group {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
//.form-group .input-group {
|
||||
// margin-bottom: 5px;
|
||||
//}
|
||||
|
||||
.op_box {
|
||||
display: block;
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
|
||||
{% block block_body %}
|
||||
<div class="page-content-inner">
|
||||
{# ## 防止页面搜索框被自动填充#}
|
||||
{# ## 防止页面搜索框被自动填充#}
|
||||
<label style="display:none;"><span></span><input type="text" name="hidden1"></label>
|
||||
<label style="display:none;"><span></span><input type="password" name="hidden2"></label>
|
||||
|
||||
|
@ -136,12 +136,12 @@
|
|||
|
||||
<div class="form-horizontal">
|
||||
|
||||
{# ## <div class="form-group form-group-sm">#}
|
||||
{# ## <label for="edit-host-type" class="col-sm-2 control-label require">主机类型:</label>#}
|
||||
{# ## <div class="col-sm-6">#}
|
||||
{# ## <div id="edit-host-type" class="btn-group btn-group-sm"></div>#}
|
||||
{# ## </div>#}
|
||||
{# ## </div>#}
|
||||
{# ## <div class="form-group form-group-sm">#}
|
||||
{# ## <label for="edit-host-type" class="col-sm-2 control-label require">主机类型:</label>#}
|
||||
{# ## <div class="col-sm-6">#}
|
||||
{# ## <div id="edit-host-type" class="btn-group btn-group-sm"></div>#}
|
||||
{# ## </div>#}
|
||||
{# ## </div>#}
|
||||
|
||||
<div class="form-group form-group-sm">
|
||||
<label for="edit-host-os-type" class="col-sm-3 control-label require">远程主机系统:</label>
|
||||
|
@ -303,18 +303,13 @@
|
|||
<label class="col-sm-3 control-label" for="account-protocol-port"><strong>端口:</strong></label>
|
||||
<div class="col-sm-9">
|
||||
<input id="account-protocol-port" type="text" class="form-control" placeholder=""/>
|
||||
{# ## <p id="account-protocol-port-static" class="form-control-static mono" style="color:#0a6aa1;font-weight:bold;display:none;"></p>#}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group form-group-sm">
|
||||
<label class="col-sm-3 control-label" for="account-auth-type"><strong>认证方式:</strong></label>
|
||||
<div class="col-sm-9">
|
||||
<select id="account-auth-type" class="form-control">
|
||||
<option value="1">用户名/密码 认证</option>
|
||||
<option value="2">SSH私钥 认证</option>
|
||||
<option value="0">无需认证</option>
|
||||
</select>
|
||||
<select id="account-auth-type" class="form-control"></select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -358,8 +353,13 @@
|
|||
<input id="account-password" type="password" class="form-control" placeholder="登录远程主机的密码">
|
||||
<span class="input-group-btn"><button class="btn btn-sm btn-default" type="button" id="btn-show-account-password"><i class="fa fa-eye fa-fw"></i></button></span>
|
||||
</div>
|
||||
<div class="control-desc-sm-input">
|
||||
<span>如不填写密码,则会在远程连接时要求用户手动输入。</span>
|
||||
<span id="block-clear-password">如果已设置了密码,可<a href="javascript:" id="btn-clear-password">点击此处清除</a>。</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="block-sshkey" style="display:none;">
|
||||
|
|
|
@ -172,7 +172,7 @@
|
|||
placeholder="用户账号,也就是用户登录名"/>
|
||||
</div>
|
||||
<div class="col-sm-5">
|
||||
<div class="control-desc">英文字符和数字,最大32字符</div>
|
||||
<div class="control-desc-sm">英文字符和数字,最大32字符</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -189,7 +189,7 @@
|
|||
<input id="edit-user-email" type="text" class="form-control" placeholder="电子邮箱地址"/>
|
||||
</div>
|
||||
<div class="col-sm-5">
|
||||
<div class="control-desc">用于激活账号、重置密码。</div>
|
||||
<div class="control-desc-sm">用于激活账号、重置密码。</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -224,7 +224,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="col-sm-5">
|
||||
<div class="control-desc">开始</div>
|
||||
<div class="control-desc-sm">开始时间</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group form-group-sm">
|
||||
|
@ -237,7 +237,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="col-sm-5">
|
||||
<div class="control-desc">结束</div>
|
||||
<div class="control-desc-sm">结束时间</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -444,7 +444,7 @@
|
|||
placeholder="LDAP服务器IP或域名"/>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<label class="form-check-label"><input id="edit-ldap-ssl" type="checkbox" class="form-check-input"/> 使用 SSL</label>
|
||||
<label class="control-label"><input id="edit-ldap-ssl" type="checkbox"/> 使用 SSL</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -503,7 +503,7 @@
|
|||
<label for="edit-ldap-base-dn" class="col-sm-2 control-label require">用户基准DN:</label>
|
||||
<div class="col-sm-9">
|
||||
<input id="edit-ldap-base-dn" type="text" class="form-control" placeholder=""/>
|
||||
<div class="control-desc-sm">限制用户DN的范围,例如 <span class="important">ou=dev,ou=company,ou=com</span>。
|
||||
<div class="control-desc-sm-input">限制用户DN的范围,例如 <span class="important">ou=dev,ou=company,ou=com</span>。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -513,7 +513,7 @@
|
|||
<div class="col-sm-9">
|
||||
<input id="edit-ldap-filter" type="text" class="form-control" placeholder=""
|
||||
value="(&(objectClass=person))"/>
|
||||
<div class="control-desc-sm">列举用户时的过滤器,例如 <span class="important">(&(objectClass=person))</span>。
|
||||
<div class="control-desc-sm-input">列举用户时的过滤器,例如 <span class="important">(&(objectClass=person))</span>。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -109,7 +109,7 @@ class TPAssistBridge(object):
|
|||
return assist_info
|
||||
|
||||
def handle_assist_message(self, msg_req: AssistMessage):
|
||||
log.v('add message, cmd_id={}\n'.format(msg_req.cmd_id))
|
||||
# log.v('add message, cmd_id={}\n'.format(msg_req.cmd_id))
|
||||
self._commands[msg_req.cmd_id] = msg_req
|
||||
|
||||
def on_web_client_connect(self, msg_req: AssistMessage, s_id: str, param: dict) -> None:
|
||||
|
|
|
@ -126,6 +126,10 @@ controllers = [
|
|||
(r'/asset/account-group/(.*)', account.AccGroupInfoHandler),
|
||||
# - [json] 添加/更新 远程账号
|
||||
(r'/asset/update-account', account.DoUpdateAccountHandler),
|
||||
# - [json] 清除 远程账号的预设密码
|
||||
(r'/asset/clear-account-password', account.DoClearAccountPasswordHandler),
|
||||
# - [json] 查询 远程账号是否有预设密码
|
||||
(r'/asset/get-account-interactive-mode', account.DoGetAccountInteractiveModeHandler),
|
||||
# - [json] 禁用/解禁/删除 远程账号
|
||||
(r'/asset/update-accounts', account.DoUpdateAccountsHandler),
|
||||
# - [json] 获取账号列表
|
||||
|
|
|
@ -233,15 +233,15 @@ class DoUpdateAccountHandler(TPBaseJsonHandler):
|
|||
|
||||
if acc_id == -1:
|
||||
# 新增账号
|
||||
if param['auth_type'] == TP_AUTH_TYPE_PASSWORD and len(param['password']) == 0:
|
||||
return self.write_json(TPE_PARAM)
|
||||
elif param['auth_type'] == TP_AUTH_TYPE_PRIVATE_KEY and len(param['pri_key']) == 0:
|
||||
# if param['auth_type'] == TP_AUTH_TYPE_PASSWORD and len(param['password']) == 0:
|
||||
# return self.write_json(TPE_PARAM)
|
||||
if param['auth_type'] == TP_AUTH_TYPE_PRIVATE_KEY and len(param['pri_key']) == 0:
|
||||
return self.write_json(TPE_PARAM)
|
||||
|
||||
if param['auth_type'] == TP_AUTH_TYPE_PASSWORD and len(param['password']) > 0:
|
||||
code, ret_data = yield core_service_async_enc(param['password'])
|
||||
if code != TPE_OK:
|
||||
return self.write_json(code)
|
||||
return self.write_json(code, '无法加密存储密码!')
|
||||
else:
|
||||
param['password'] = ret_data
|
||||
elif param['auth_type'] == TP_AUTH_TYPE_PRIVATE_KEY and len(param['pri_key']) > 0:
|
||||
|
@ -260,6 +260,60 @@ class DoUpdateAccountHandler(TPBaseJsonHandler):
|
|||
self.write_json(err, data=info)
|
||||
|
||||
|
||||
class DoClearAccountPasswordHandler(TPBaseJsonHandler):
|
||||
@tornado.gen.coroutine
|
||||
def post(self):
|
||||
ret = self.check_privilege(TP_PRIVILEGE_ACCOUNT)
|
||||
if ret != TPE_OK:
|
||||
return
|
||||
|
||||
args = self.get_argument('args', None)
|
||||
if args is None:
|
||||
return self.write_json(TPE_PARAM)
|
||||
try:
|
||||
args = json.loads(args)
|
||||
except:
|
||||
return self.write_json(TPE_JSON_FORMAT)
|
||||
|
||||
try:
|
||||
host_id = int(args['host_id'])
|
||||
acc_id = int(args['acc_id'])
|
||||
except:
|
||||
log.e('\n')
|
||||
return self.write_json(TPE_PARAM)
|
||||
|
||||
err = account.clear_account_password(self, host_id, acc_id)
|
||||
self.write_json(err)
|
||||
|
||||
|
||||
class DoGetAccountInteractiveModeHandler(TPBaseJsonHandler):
|
||||
@tornado.gen.coroutine
|
||||
def post(self):
|
||||
ret = self.check_privilege(TP_PRIVILEGE_OPS)
|
||||
if ret != TPE_OK:
|
||||
return
|
||||
|
||||
args = self.get_argument('args', None)
|
||||
if args is None:
|
||||
return self.write_json(TPE_PARAM)
|
||||
try:
|
||||
args = json.loads(args)
|
||||
except:
|
||||
return self.write_json(TPE_JSON_FORMAT)
|
||||
|
||||
try:
|
||||
acc_id = int(args['acc_id'])
|
||||
except:
|
||||
log.e('\n')
|
||||
return self.write_json(TPE_PARAM)
|
||||
|
||||
err, password = account.get_account_password(acc_id)
|
||||
if err != TPE_OK:
|
||||
return self.write_json(err)
|
||||
|
||||
self.write_json(TPE_OK, data={'is_interactive': True if len(password) == 0 else False})
|
||||
|
||||
|
||||
class DoUpdateAccountsHandler(TPBaseJsonHandler):
|
||||
@tornado.gen.coroutine
|
||||
def post(self):
|
||||
|
|
|
@ -421,9 +421,9 @@ class DoGetSessionIDHandler(TPBaseJsonHandler):
|
|||
conn_info['_enc'] = 0
|
||||
|
||||
if acc_id == -1:
|
||||
if auth_type == TP_AUTH_TYPE_PASSWORD and len(password) == 0:
|
||||
return self.write_json(TPE_PARAM)
|
||||
elif auth_type == TP_AUTH_TYPE_PRIVATE_KEY and len(pri_key) == 0:
|
||||
# if auth_type == TP_AUTH_TYPE_PASSWORD and len(password) == 0:
|
||||
# return self.write_json(TPE_PARAM)
|
||||
if auth_type == TP_AUTH_TYPE_PRIVATE_KEY and len(pri_key) == 0:
|
||||
return self.write_json(TPE_PARAM)
|
||||
else:
|
||||
if (auth_type == TP_AUTH_TYPE_PASSWORD and len(password) == 0) or (auth_type == TP_AUTH_TYPE_PRIVATE_KEY and len(pri_key) == 0):
|
||||
|
|
|
@ -61,7 +61,7 @@ class AssistHandler(tornado.websocket.WebSocketHandler):
|
|||
'method': msg.method,
|
||||
'param': param
|
||||
}
|
||||
log.w('send ws request: {}\n'.format(json_encode(data)))
|
||||
log.d('send ws request: {}\n'.format(json_encode(data)))
|
||||
self.write_message(json_encode(data))
|
||||
|
||||
def send_response(self, msg: AssistMessage, code, message='', data=None):
|
||||
|
@ -75,7 +75,7 @@ class AssistHandler(tornado.websocket.WebSocketHandler):
|
|||
'message': message,
|
||||
'data': data
|
||||
}
|
||||
log.w('send ws response: {}\n'.format(json_encode(ret)))
|
||||
log.d('send ws response: {}\n'.format(json_encode(ret)))
|
||||
self.write_message(json_encode(ret))
|
||||
|
||||
def set_assist_id(self, assist_id: int) -> None:
|
||||
|
|
|
@ -296,6 +296,32 @@ def add_account(handler, host_id, args):
|
|||
return TPE_OK, _id
|
||||
|
||||
|
||||
def clear_account_password(handler, host_id, acc_id):
|
||||
db = get_db()
|
||||
sql = 'UPDATE `{tp}acc` SET `password`="" WHERE `id`={ph} AND `host_id`={ph}'.format(tp=db.table_prefix, ph=db.place_holder)
|
||||
db_ret = db.exec(sql, (acc_id, host_id))
|
||||
if not db_ret:
|
||||
return TPE_DATABASE
|
||||
|
||||
return TPE_OK
|
||||
|
||||
|
||||
def get_account_password(acc_id):
|
||||
db = get_db()
|
||||
s = SQL(db)
|
||||
s.select_from('acc', ['password'], alt_name='a')
|
||||
s.where('a.id={ph}'.format(ph=db.place_holder))
|
||||
err = s.query((acc_id, ))
|
||||
if err != TPE_OK:
|
||||
return err, None
|
||||
if len(s.recorder) != 1:
|
||||
return TPE_DATABASE, None
|
||||
|
||||
# s.recorder[0]['_host'] = sh.recorder[0]
|
||||
|
||||
return TPE_OK, s.recorder[0]['password']
|
||||
|
||||
|
||||
def update_account(handler, host_id, acc_id, args):
|
||||
"""
|
||||
更新一个远程账号
|
||||
|
|
Loading…
Reference in New Issue