diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 3f94861..23578e4 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -9,17 +9,7 @@
-
-
-
-
-
-
-
-
-
-
-
+
@@ -30,7 +20,6 @@
-
-
+
+
@@ -88,7 +79,7 @@
-
+
@@ -208,13 +199,6 @@
-
-
-
-
-
-
-
@@ -382,23 +366,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -416,124 +383,171 @@
-
+
-
-
+
+
-
+
-
+
-
-
+
+
-
+
-
-
+
+
-
+
-
+
+
+
+
-
-
+
+
-
+
-
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
-
+
-
-
-
-
-
+
+
-
+
-
-
+
+
-
+
-
-
+
+
-
+
-
+
-
-
+
+
+
+
+
-
+
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
diff --git a/README.md b/README.md
index 7bea9d3..33ce204 100644
--- a/README.md
+++ b/README.md
@@ -61,6 +61,8 @@ sh start_docker.sh



+
+
# TODO LISTS
@@ -93,7 +95,9 @@ sh start_docker.sh
- [ ] 批量脚本
- [x] webssh终端
- [x] webtelnet终端
-- [x] 查看在线会话
+- [x] 查看在线会话列表
+- [x] 实时查看在线会话
+- [ ] 锁定实时在线会话
- [x] 强制关闭在线会话
- [ ] 文件上传
- [ ] 文件下载
diff --git a/db.sqlite3 b/db.sqlite3
index 9845a2a..5cc78ff 100644
Binary files a/db.sqlite3 and b/db.sqlite3 differ
diff --git a/layer.py b/layer.py
index 94a710a..76bc46a 100644
--- a/layer.py
+++ b/layer.py
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+""" 初始化创建 admin 账号"""
import os
import sys
@@ -10,14 +11,18 @@ def main():
# 让django初始化
import django
django.setup()
+
+ from user.models import User
+ from util.tool import hash_code
+
from channels.layers import get_channel_layer
from asgiref.sync import async_to_sync
channel_layer = get_channel_layer()
- async_to_sync(channel_layer.send)("specific.FEfncEYP!bFdhrEmvyBIV", {
+ async_to_sync(channel_layer.send)('specific.WjcnLeaL!oejCJLfYFOdT', {
"type": "chat.message",
- "text": '{"status":2, "message":"\\n\\rAdministrator forcibly interrupts your connection"}',
+ "text": '{"status":3, "message":"系统即将关闭,请退出当前会话!"}',
})
-
-
+
+
if __name__ == '__main__':
main()
diff --git a/layer_group.py b/layer_group.py
new file mode 100644
index 0000000..1d2cf35
--- /dev/null
+++ b/layer_group.py
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+import os
+import sys
+
+
+def main():
+ # 使用django配置文件进行设置
+ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'devops.settings')
+
+ # 让django初始化
+ import django
+ django.setup()
+
+ from user.models import User
+ from util.tool import hash_code
+
+ from channels.layers import get_channel_layer
+ from asgiref.sync import async_to_sync
+ channel_layer = get_channel_layer()
+ async_to_sync(channel_layer.group_send)('session_NbxeEnGcUv', {
+ "type": "chat.message",
+ "text": '{"status":3, "message":"系统即将关闭,请退出当前会话!- 来自组"}',
+ })
+
+
+if __name__ == '__main__':
+ main()
diff --git a/screenshots/36.PNG b/screenshots/36.PNG
new file mode 100644
index 0000000..ac1bbca
Binary files /dev/null and b/screenshots/36.PNG differ
diff --git a/screenshots/37.JPG b/screenshots/37.JPG
new file mode 100644
index 0000000..7d5bb8b
Binary files /dev/null and b/screenshots/37.JPG differ
diff --git a/static/webssh/webssh.js b/static/webssh/webssh.js
index d213c72..4a00ade 100644
--- a/static/webssh/webssh.js
+++ b/static/webssh/webssh.js
@@ -57,7 +57,7 @@ function websocket() {
var status = data.status;
if (status === 0) {
term.write(message)
- } else {
+ } else if (status === 1 || status === 2 ) {
//window.location.reload() 端口连接后刷新页面
//term.clear()
term.write(message)
@@ -71,7 +71,18 @@ function websocket() {
//term.dispose()
//$('#django-webssh-terminal').addClass('hide');
//$('#form').removeClass('hide');
- }
+ } else if (status === 3 ) {
+ console.log(message);
+ toastr.options.closeButton = true;
+ toastr.options.showMethod = 'slideDown';
+ toastr.options.hideMethod = 'fadeOut';
+ toastr.options.closeMethod = 'fadeOut';
+ toastr.options.timeOut = 0;
+ toastr.options.extendedTimeOut = 0;
+ toastr.options.progressBar = true;
+ toastr.options.positionClass = 'toast-top-right';
+ toastr.warning(message);
+ };
});
/*
@@ -79,13 +90,13 @@ function websocket() {
* status 为 1 时, resize pty ssh 终端大小, cols 为每行显示的最大字数, rows 为每列显示的最大字数, 忽略 data 参数
*/
var message = {'status': 0, 'data': null, 'cols': null, 'rows': null};
-
+
// 向服务器端发送数据
term.on('data', function (data) {
message['status'] = 0;
message['data'] = data;
var send_data = JSON.stringify(message);
- sock.send(send_data)
+ sock.send(send_data);
});
// 监听浏览器窗口, 根据浏览器窗口大小修改终端大小
diff --git a/static/webssh/webssh.view.js b/static/webssh/webssh.view.js
new file mode 100644
index 0000000..09eadd7
--- /dev/null
+++ b/static/webssh/webssh.view.js
@@ -0,0 +1,115 @@
+function checkwindow() {
+ event.returnValue=false;
+}
+
+function get_connect_info() {
+ var group = $.trim($('#group').text());
+ var connect_info = 'group=' + group;
+ return connect_info
+}
+
+function get_term_size() {
+ var init_width = 9;
+ var init_height = 17;
+
+ var windows_width = $(window).width();
+ var windows_height = $(window).height();
+
+ return {
+ cols: Math.floor(windows_width / init_width),
+ rows: Math.floor(windows_height / init_height),
+ }
+}
+
+function websocket() {
+ var cols = get_term_size().cols;
+ var rows = get_term_size().rows;
+ var connect_info = get_connect_info();
+
+ var term = new Terminal(
+ {
+ cols: cols,
+ rows: rows,
+ useStyle: true,
+ cursorBlink: true
+ }
+ ),
+ protocol = (location.protocol === 'https:') ? 'wss://' : 'ws://',
+ socketURL = protocol + location.hostname + ((location.port) ? (':' + location.port) : '') + '/webssh/view/?' + connect_info;
+
+ var sock;
+ sock = new WebSocket(socketURL);
+
+ // 打开 websocket 连接, 打开 web 终端
+ sock.addEventListener('open', function () {
+ //$('#django-webssh-terminal').removeClass('hide');
+ term.open(document.getElementById('terminal'));
+ //term.focus();
+ //term.write('Connecting...\n\r');
+ $("body").attr("onbeforeunload",'checkwindow()'); //增加刷新关闭提示属性
+
+ });
+
+ // 读取服务器端发送的数据并写入 web 终端
+ sock.addEventListener('message', function (recv) {
+ var data = JSON.parse(recv.data);
+ var message = data.message;
+ var status = data.status;
+ if (status === 0) {
+ term.write(message)
+ } else if (status === 1 || status === 2 ) {
+ //window.location.reload() 端口连接后刷新页面
+ //term.clear()
+ term.write(message)
+ $("body").removeAttr("onbeforeunload"); //删除刷新关闭提示属性
+
+ //$(document).keyup(function(event){ // 监听回车按键事件
+ // if(event.keyCode == 13){
+ //window.location.reload();
+ // }
+ //});
+ //term.dispose()
+ //$('#django-webssh-terminal').addClass('hide');
+ //$('#form').removeClass('hide');
+ } else if (status === 3 ) {
+ console.log(message);
+ toastr.options.closeButton = true;
+ toastr.options.showMethod = 'slideDown';
+ toastr.options.hideMethod = 'fadeOut';
+ toastr.options.closeMethod = 'fadeOut';
+ toastr.options.timeOut = 0;
+ toastr.options.extendedTimeOut = 0;
+ toastr.options.progressBar = true;
+ toastr.options.positionClass = 'toast-top-right';
+ toastr.warning(message);
+ } else if (status === 5 ) {
+ term.write(message)
+ };
+ });
+
+ /*
+ * status 为 0 时, 将用户输入的数据通过 websocket 传递给后台, data 为传递的数据, 忽略 cols 和 rows 参数
+ * status 为 1 时, resize pty ssh 终端大小, cols 为每行显示的最大字数, rows 为每列显示的最大字数, 忽略 data 参数
+ */
+ var message = {'status': 0, 'data': null, 'cols': null, 'rows': null};
+
+ // 向服务器端发送数据
+ term.on('data', function (data) {
+ //message['status'] = 0;
+ //message['data'] = data;
+ //var send_data = JSON.stringify(message);
+ //sock.send(send_data);
+ });
+
+ // 监听浏览器窗口, 根据浏览器窗口大小修改终端大小
+ $(window).resize(function () {
+ var cols = get_term_size().cols;
+ var rows = get_term_size().rows;
+ //message['status'] = 1;
+ //message['cols'] = cols;
+ //message['rows'] = rows;
+ //var send_data = JSON.stringify(message);
+ //sock.send(send_data);
+ term.resize(cols, rows)
+ })
+}
diff --git a/static/webtelnet/webtelnet.js b/static/webtelnet/webtelnet.js
index f314597..086a454 100644
--- a/static/webtelnet/webtelnet.js
+++ b/static/webtelnet/webtelnet.js
@@ -59,7 +59,7 @@ function websocket() {
var status = data.status;
if (status === 0) {
term.write(message)
- } else {
+ } else if (status === 1 || status === 2 ) {
//window.location.reload() 端口连接后刷新页面
//term.clear()
term.write(message)
@@ -73,7 +73,18 @@ function websocket() {
//term.dispose()
//$('#django-webssh-terminal').addClass('hide');
//$('#form').removeClass('hide');
- }
+ } else if (status === 3 ) {
+ console.log(message);
+ toastr.options.closeButton = true;
+ toastr.options.showMethod = 'slideDown';
+ toastr.options.hideMethod = 'fadeOut';
+ toastr.options.closeMethod = 'fadeOut';
+ toastr.options.timeOut = 0;
+ toastr.options.extendedTimeOut = 0;
+ toastr.options.progressBar = true;
+ toastr.options.positionClass = 'toast-top-right';
+ toastr.warning(message);
+ };
});
/*
diff --git a/templates/server/host.html b/templates/server/host.html
index b4b4f8d..199e788 100644
--- a/templates/server/host.html
+++ b/templates/server/host.html
@@ -22,13 +22,15 @@
{% endblock navheader %}
{% block content %}
-