From 4cdc7f33ced3fe77d9bb31055a798f778ddbba8d Mon Sep 17 00:00:00 2001 From: ibuler Date: Sun, 22 Nov 2015 20:20:32 +0800 Subject: [PATCH 1/8] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- connect.py | 24 +++++++++++++++++++----- templates/nav.html | 2 -- templates/setting.html | 20 ++++++++++---------- 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/connect.py b/connect.py index 05d84dd8f..23eb92bdb 100644 --- a/connect.py +++ b/connect.py @@ -504,24 +504,33 @@ class Nav(object): def search(self, str_r=''): gid_pattern = re.compile(r'^g\d+$') + # 获取用户授权的所有主机信息 if not self.user_perm: self.user_perm = get_group_user_perm(self.user) user_asset_all = self.user_perm.get('asset').keys() + # 搜索结果保存 user_asset_search = [] if str_r: + # 资产组组id匹配 if gid_pattern.match(str_r): - user_asset_search = list(Asset.objects.all()) + gid = int(str_r.lstrip('g')) + # 获取资产组包含的资产 + user_asset_search = get_object(AssetGroup, id=gid).asset_set.all() else: + # 匹配 ip, hostname, 备注 for asset in user_asset_all: - if str_r in asset.ip or str_r in str(asset.comment): + if str_r in asset.ip or str_r in str(asset.hostname) or str_r in str(asset.comment): user_asset_search.append(asset) else: + # 如果没有输入就展现所有 user_asset_search = user_asset_all self.search_result = dict(zip(range(len(user_asset_search)), user_asset_search)) print '\033[32m[%-3s] %-15s %-15s %-5s %-10s %s \033[0m' % ('ID', 'AssetName', 'IP', 'Port', 'Role', 'Comment') for index, asset in self.search_result.items(): + # 获取该资产信息 asset_info = get_asset_info(asset) + # 获取该资产包含的角色 role = [str(role.name) for role in self.user_perm.get('asset').get(asset).get('role')] if asset.comment: print '[%-3s] %-15s %-15s %-5s %-10s %s' % (index, asset.hostname, asset.ip, asset_info.get('port'), @@ -530,9 +539,11 @@ class Nav(object): print '[%-3s] %-15s %-15s %-5s %-10s' % (index, asset.hostname, asset.ip, asset_info.get('port'), role) print - @staticmethod - def print_asset_group(): - user_asset_group_all = AssetGroup.objects.all() + def print_asset_group(self): + """ + 打印用户授权的资产组 + """ + user_asset_group_all = get_group_user_perm(self.user).get('asset_group', []) print '\033[32m[%-3s] %-15s %s \033[0m' % ('ID', 'GroupName', 'Comment') for asset_group in user_asset_group_all: @@ -543,6 +554,9 @@ class Nav(object): print def exec_cmd(self): + """ + 批量执行命令 + """ self.search() while True: print "请输入主机名、IP或ansile支持的pattern, q退出" diff --git a/templates/nav.html b/templates/nav.html index df3e3d358..bbcf4c26e 100644 --- a/templates/nav.html +++ b/templates/nav.html @@ -36,8 +36,6 @@
  • 系统角色
  • -
  • 权限审批
  • -
  • 授权记录
  • diff --git a/templates/setting.html b/templates/setting.html index 55a49ba7c..7fa097150 100644 --- a/templates/setting.html +++ b/templates/setting.html @@ -29,7 +29,7 @@ @@ -82,15 +82,15 @@ -
    - - - - - - -
    组名
    -
    +{#
    #} +{# #} +{# #} +{# #} +{# #} +{# #} +{# #} +{#
    组名
    #} +{#
    #} From eb779e5bf64a3c153fb5160a27644898a895cd1d Mon Sep 17 00:00:00 2001 From: ibuler Date: Sun, 22 Nov 2015 21:59:07 +0800 Subject: [PATCH 2/8] =?UTF-8?q?=E4=BF=AE=E6=94=B9run=5Fwebsocket?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- connect.py | 38 ++++++++------------------------------ run_websocket.py | 30 ++++++++++++++++++++---------- 2 files changed, 28 insertions(+), 40 deletions(-) diff --git a/connect.py b/connect.py index 00ece2f60..cf0824a7d 100644 --- a/connect.py +++ b/connect.py @@ -19,7 +19,7 @@ import struct, fcntl, signal, socket, select os.environ['DJANGO_SETTINGS_MODULE'] = 'jumpserver.settings' if django.get_version() != '1.6': django.setup() -from jumpserver.api import ServerError, User, Asset, AssetGroup, get_object, mkdir, get_asset_info, get_role +from jumpserver.api import ServerError, User, Asset, PermRole, AssetGroup, get_object, mkdir, get_asset_info, get_role from jumpserver.api import logger, Log, TtyLog, get_role_key from jperm.perm_api import gen_resource, get_group_asset_perm, get_group_user_perm from jumpserver.settings import LOG_DIR @@ -69,6 +69,8 @@ class Tty(object): self.connect_info = None self.login_type = 'ssh' self.vim_flag = False + self.ps1_pattern = re.compile('\[.*@.*\][\$#]') + self.vim_data = '' @staticmethod def is_output(strings): @@ -161,27 +163,6 @@ class Tty(object): else: return '' - @staticmethod - def remove_control_char(str_r): - """ - 处理日志特殊字符 - """ - control_char = re.compile(r""" - \x1b[ #%()*+\-.\/]. | - \r | #匹配 回车符(CR) - (?:\x1b\[|\x9b) [ -?]* [@-~] | #匹配 控制顺序描述符(CSI)... Cmd - (?:\x1b\]|\x9d) .*? (?:\x1b\\|[\a\x9c]) | \x07 | #匹配 操作系统指令(OSC)...终止符或振铃符(ST|BEL) - (?:\x1b[P^_]|[\x90\x9e\x9f]) .*? (?:\x1b\\|\x9c) | #匹配 设备控制串或私讯或应用程序命令(DCS|PM|APC)...终止符(ST) - \x1b. #匹配 转义过后的字符 - [\x80-\x9f] #匹配 所有控制字符 - """, re.X) - backspace = re.compile(r"[^\b][\b]") - line_filtered = control_char.sub('', str_r.rstrip()) - while backspace.search(line_filtered): - line_filtered = backspace.sub('', line_filtered) - - return line_filtered - def get_log(self): """ Logging user command and output. @@ -312,9 +293,7 @@ class SshTty(Tty): log_file_f, log_time_f, log = self.get_log() old_tty = termios.tcgetattr(sys.stdin) pre_timestamp = time.time() - pattern = re.compile('\[.*@.*\][\$#]') data = '' - chan_str = '' input_mode = False try: tty.setraw(sys.stdin.fileno()) @@ -333,7 +312,7 @@ class SshTty(Tty): if len(x) == 0: break if self.vim_flag: - chan_str += x + self.vim_data += x sys.stdout.write(x) sys.stdout.flush() now_timestamp = time.time() @@ -352,21 +331,20 @@ class SshTty(Tty): if sys.stdin in r: x = os.read(sys.stdin.fileno(), 1) input_mode = True - if str(x) in ['\r', '\n', '\r\n']: if self.vim_flag: - match = pattern.search(chan_str) + match = self.ps1_pattern.search(self.vim_data) if match: self.vim_flag = False - data = self.deal_command(data) + data = self.deal_command(data)[0:200] if len(data) > 0: TtyLog(log=log, datetime=datetime.datetime.now(), cmd=data).save() else: - data = self.deal_command(data) + data = self.deal_command(data)[0:200] if len(data) > 0: TtyLog(log=log, datetime=datetime.datetime.now(), cmd=data).save() data = '' - chan_str = '' + self.vim_data = '' input_mode = False if len(x) == 0: diff --git a/run_websocket.py b/run_websocket.py index 9d565fe42..bb8a0a8ff 100644 --- a/run_websocket.py +++ b/run_websocket.py @@ -20,15 +20,9 @@ from tornado.websocket import WebSocketClosedError from tornado.options import define, options from pyinotify import WatchManager, Notifier, ProcessEvent, IN_DELETE, IN_CREATE, IN_MODIFY, AsyncNotifier +import select -# from gevent import monkey -# monkey.patch_all() -# import gevent -# from gevent.socket import wait_read, wait_write -import struct, fcntl, signal, socket, select, fnmatch - -import paramiko -from connect import Tty +from connect import Tty, User, Asset, PermRole from connect import TtyLog, Log try: @@ -217,7 +211,10 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler): username = self.get_argument('username', '') token = self.get_argument('token', '') print asset_name, username, token - self.term = WebTty('a', 'b') + user = User.objects.get(username='lastimac') + asset = Asset.objects.get(ip='192.168.244.129') + role = PermRole.objects.get(name='dev') + self.term = WebTty(user, asset, role) self.term.get_connection() self.term.channel = self.term.ssh.invoke_shell(term='xterm') WebTerminalHandler.tasks.append(MyThread(target=self.forward_outbound)) @@ -236,7 +233,17 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler): if data.get('data'): self.term.input_mode = True if str(data['data']) in ['\r', '\n', '\r\n']: - TtyLog(log=self.log, datetime=datetime.datetime.now(), cmd=self.term.deal_command(self.term.data, self.term.ssh)).save() + if self.term.vim_flag: + match = self.term.ps1_pattern.search(self.term.vim_data) + if match: + self.term.vim_flag = False + vim_data = self.term.deal_command(self.term.vim_data)[0:200] + if len(data) > 0: + TtyLog(log=self.log, datetime=datetime.datetime.now(), cmd=vim_data).save() + + TtyLog(log=self.log, datetime=datetime.datetime.now(), + cmd=self.term.deal_command(self.term.data)[0:200]).save() + self.term.vim_data = '' self.term.data = '' self.term.input_mode = False self.term.channel.send(data['data']) @@ -267,6 +274,8 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler): if not len(recv): return data += recv + if self.term.vim_flag: + self.term.vim_data += recv try: self.write_message(json.dumps({'data': data})) now_timestamp = time.time() @@ -290,4 +299,5 @@ if __name__ == '__main__': server.bind(options.port, options.host) # server.listen(options.port) server.start(num_processes=1) + print "Run server on %s:%s" % (options.host, options.port) tornado.ioloop.IOLoop.instance().start() From ee218a5fedbb81a5938485534f895cd409aa8148 Mon Sep 17 00:00:00 2001 From: kelianchun_miller <360271747@qq.com> Date: Mon, 23 Nov 2015 12:47:02 +0800 Subject: [PATCH 3/8] update connect.py --- connect.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connect.py b/connect.py index 00ece2f60..13649c270 100644 --- a/connect.py +++ b/connect.py @@ -155,7 +155,7 @@ class Tty(object): """, re.X) result_command = control_char.sub('', result_command.strip()) if not self.vim_flag: - if result_command.startswith('vi'): + if result_command.startswith('vi') or result_command.startswith('fg'): self.vim_flag = True return result_command.decode('utf8', "ignore") else: From f49a92e742fe8513c0e3677cbfc023ae8452c8e6 Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 23 Nov 2015 15:34:28 +0800 Subject: [PATCH 4/8] =?UTF-8?q?webscoket=E6=8E=88=E6=9D=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- connect.py | 3 ++- jlog/views.py | 7 ++---- jperm/perm_api.py | 9 ++++++++ run_websocket.py | 55 ++++++++++++++++++++++++++++++++++++----------- 4 files changed, 55 insertions(+), 19 deletions(-) diff --git a/connect.py b/connect.py index e84aa141e..d16d9d7b6 100644 --- a/connect.py +++ b/connect.py @@ -19,9 +19,10 @@ import struct, fcntl, signal, socket, select os.environ['DJANGO_SETTINGS_MODULE'] = 'jumpserver.settings' if django.get_version() != '1.6': django.setup() +from django.contrib.sessions.models import Session from jumpserver.api import ServerError, User, Asset, PermRole, AssetGroup, get_object, mkdir, get_asset_info, get_role from jumpserver.api import logger, Log, TtyLog, get_role_key -from jperm.perm_api import gen_resource, get_group_asset_perm, get_group_user_perm +from jperm.perm_api import gen_resource, get_group_asset_perm, get_group_user_perm, user_have_perm from jumpserver.settings import LOG_DIR from jperm.ansible_api import Command diff --git a/jlog/views.py b/jlog/views.py index 0e3ee2ade..d5f38852d 100644 --- a/jlog/views.py +++ b/jlog/views.py @@ -104,10 +104,7 @@ def log_record(request): def web_terminal(request): - #username = get_session.get('username', '') - token = request.COOKIES.get('sessionid') - username = request.user.username - asset_name = '127.0.0.1' - web_terminal_uri = 'ws://%s/terminal?username=%s&asset_name=%s&token=%s' % (WEB_SOCKET_HOST, username, asset_name, token) + asset_id = 15 + web_terminal_uri = 'ws://%s/terminal?asset_id=%s' % (WEB_SOCKET_HOST, asset_id) return render_to_response('jlog/web_terminal.html', locals()) diff --git a/jperm/perm_api.py b/jperm/perm_api.py index f79040c60..2bd6de632 100644 --- a/jperm/perm_api.py +++ b/jperm/perm_api.py @@ -132,6 +132,15 @@ def get_group_asset_perm(ob): return perm +def user_have_perm(user, asset): + user_perm_all = get_group_user_perm(user) + user_assets = user_perm_all.get('asset').keys() + if asset in user_assets: + return user_perm_all.get('asset').get(asset).get('role') + else: + return False + + def gen_resource(ob, ex='', perm=None): """ ob为用户或资产列表或资产queryset, 如果同时输入用户和资产,则获取用户在这些资产上的信息 diff --git a/run_websocket.py b/run_websocket.py index bb8a0a8ff..d2b76e36c 100644 --- a/run_websocket.py +++ b/run_websocket.py @@ -23,7 +23,7 @@ from pyinotify import WatchManager, Notifier, ProcessEvent, IN_DELETE, IN_CREATE import select from connect import Tty, User, Asset, PermRole -from connect import TtyLog, Log +from connect import TtyLog, Log, Session, user_have_perm try: import simplejson as json @@ -37,14 +37,44 @@ define("host", default='0.0.0.0', help="run port on", type=str) def require_auth(func): def _deco(request, *args, **kwargs): - username = request.get_argument('username', '') - asset_name = request.get_argument('asset_name', '') - token = request.get_argument('token', '') - print username, asset_name, token - client = tornado.httpclient.HTTPClient() - # response = client.fetch('http://some/url') + urllib.urlencode({'username': username, - # 'asset_name': asset_name, 'token': token}) - # return request.close() + if request.get_cookie('sessionid'): + session_key = request.get_cookie('sessionid') + else: + session_key = request.get_secure_cookie('sessionid') + + print "session: " + session_key + + if not session_key: + print('Auth Failed') + request.close() + + session = Session.objects.filter(session_key=session_key) + if not session: + print('Auth Failed') + request.close() + else: + session = session[0] + uid = session.get_decoded().get('_auth_user_id') + user = User.objects.filter(id=uid) + asset_id = request.get_argument('asset_id', 9999) + + asset = Asset.objects.filter(id=asset_id) + if asset: + asset = asset[0] + request.asset = asset + role = user_have_perm(user, asset) + request.role = role + else: + role = '' + + if user: + user = user[0] + request.user = user + + else: + print("No session user.") + request.close() + return func(request, *args, **kwargs) return _deco @@ -200,6 +230,8 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler): self.log_time_f = None self.log = None self.id = 0 + self.asset = None + self.user = None super(WebTerminalHandler, self).__init__(*args, **kwargs) def check_origin(self, origin): @@ -207,10 +239,7 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler): @require_auth def open(self): - asset_name = self.get_argument('asset_name', '') - username = self.get_argument('username', '') - token = self.get_argument('token', '') - print asset_name, username, token + print self.user, self.asset user = User.objects.get(username='lastimac') asset = Asset.objects.get(ip='192.168.244.129') role = PermRole.objects.get(name='dev') From 483ca9677c49cab9b74b9ba8164e11993f384283 Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 23 Nov 2015 18:39:38 +0800 Subject: [PATCH 5/8] =?UTF-8?q?=E8=B5=84=E4=BA=A7=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=BF=9E=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jlog/urls.py | 1 + jlog/views.py | 15 +++++++++-- jumpserver/templatetags/mytags.py | 9 +++++++ run_websocket.py | 19 ++++++++++---- templates/jasset/asset_list.html | 42 ++++++++++++++++++++++++++++++- 5 files changed, 78 insertions(+), 8 deletions(-) diff --git a/jlog/urls.py b/jlog/urls.py index 0058bcfe6..deb2902b4 100644 --- a/jlog/urls.py +++ b/jlog/urls.py @@ -9,4 +9,5 @@ urlpatterns = patterns('', url(r'^log_kill/', log_kill), url(r'^record/$', log_record), url(r'^web_terminal/$', web_terminal), + url(r'^get_role_name/$', get_role_name), ) \ No newline at end of file diff --git a/jlog/views.py b/jlog/views.py index d5f38852d..20b7f7c98 100644 --- a/jlog/views.py +++ b/jlog/views.py @@ -4,6 +4,7 @@ from django.template import RequestContext from django.shortcuts import render_to_response from jumpserver.api import * +from jperm.perm_api import user_have_perm from django.http import HttpResponseNotFound from jlog.log_api import renderTemplate @@ -103,8 +104,18 @@ def log_record(request): return HttpResponse('无日志记录!') +def get_role_name(request): + asset_id = request.GET.get('id', 9999) + asset = get_object(Asset, id=asset_id) + if asset: + role = user_have_perm(request.user, asset=asset) + return HttpResponse(','.join(list(role))) + return HttpResponse('dev,sa') + + +@require_role() def web_terminal(request): - asset_id = 15 - web_terminal_uri = 'ws://%s/terminal?asset_id=%s' % (WEB_SOCKET_HOST, asset_id) + asset_id = request.GET.get('id') + web_terminal_uri = 'ws://%s/terminal?id=%s&role=dev' % (WEB_SOCKET_HOST, asset_id) return render_to_response('jlog/web_terminal.html', locals()) diff --git a/jumpserver/templatetags/mytags.py b/jumpserver/templatetags/mytags.py index 5af20cdd6..c8f5debde 100644 --- a/jumpserver/templatetags/mytags.py +++ b/jumpserver/templatetags/mytags.py @@ -237,3 +237,12 @@ def key_exist(username): return True else: return False + + +@register.filter(name='check_role') +def check_role(asset_id, user): + """ + ssh key is exist or not + """ + return user + diff --git a/run_websocket.py b/run_websocket.py index d2b76e36c..27420b4ea 100644 --- a/run_websocket.py +++ b/run_websocket.py @@ -56,7 +56,7 @@ def require_auth(func): session = session[0] uid = session.get_decoded().get('_auth_user_id') user = User.objects.filter(id=uid) - asset_id = request.get_argument('asset_id', 9999) + asset_id = int(request.get_argument('id', 9999)) asset = Asset.objects.filter(id=asset_id) if asset: @@ -240,10 +240,19 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler): @require_auth def open(self): print self.user, self.asset - user = User.objects.get(username='lastimac') - asset = Asset.objects.get(ip='192.168.244.129') - role = PermRole.objects.get(name='dev') - self.term = WebTty(user, asset, role) + role_name = self.get_argument('role', 'root') + roles = user_have_perm(self.user, self.asset) + login_role = '' + for role in roles: + if role.name == role_name: + login_role = role + break + if not login_role: + print "no role" + self.close() + return + # Todo: 判断 + self.term = WebTty(self.user, self.asset, login_role) self.term.get_connection() self.term.channel = self.term.ssh.invoke_shell(term='xterm') WebTerminalHandler.tasks.append(MyThread(target=self.forward_outbound)) diff --git a/templates/jasset/asset_list.html b/templates/jasset/asset_list.html index fe03cc1a2..eb37d5030 100644 --- a/templates/jasset/asset_list.html +++ b/templates/jasset/asset_list.html @@ -130,6 +130,7 @@ 详情 {% ifnotequal session_role_id 0 %} 编辑 + 连接 删除 {% endifnotequal %} @@ -167,9 +168,46 @@ } ) } - }) + }); + + $('.conn').click(function(evt){ + var url='/jlog/get_role_name/?id' + $(this).attr('value'); + var href = $(this).attr('href'); + var new_url = '/jlog/web_terminal/?id=' + $(this).attr('value') + '&role='; + $.ajax({ + type: 'GET', + url: url, + data: {}, + success: function(data){ + var dataArray = data.split(','); + if (dataArray.length == 1){ + window.open(new_url + data, '播放', 'height=400, width=600, top=89px, left=99px,toolbar=no,menubar=no,scrollbars=auto,resizeable=no,location=no,status=no'); + } else if (dataArray.length == 0){ + layer.alert('没有授权角色') + } else { + aUrl = ''; + $.each(dataArray, function(index, value){ + aUrl += '' + value + ' ' + }); + layer.alert(aUrl, { + skin: 'layui-layer-molv', + title: '多个角色,请选择一个连接', + closeBtn: 0 + }) + } + + } + }); + return false + }); }); + function windowOpen(aTab){ + var new_url = aTab.href; + window.open(new_url, '播放', 'height=400, width=600, top=89px, left=99px,toolbar=no,menubar=no,scrollbars=auto,resizeable=no,location=no,status=no'); + return false + } + $(".iframe").on('click', function(){ var asset_id_all = getIDall(); if (asset_id_all == ''){ @@ -206,6 +244,8 @@ }); }); + + $('#asset_del').click(function () { var asset_id_all = getIDall(); if (asset_id_all == ''){ From 4c5055124940d6177a02f49e2b44fb3c808b98b1 Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 23 Nov 2015 19:15:52 +0800 Subject: [PATCH 6/8] fix some bug --- jlog/views.py | 4 ++-- run_websocket.py | 7 +++---- templates/jasset/asset_list.html | 12 ++++++------ 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/jlog/views.py b/jlog/views.py index 20b7f7c98..82a4891e7 100644 --- a/jlog/views.py +++ b/jlog/views.py @@ -109,8 +109,8 @@ def get_role_name(request): asset = get_object(Asset, id=asset_id) if asset: role = user_have_perm(request.user, asset=asset) - return HttpResponse(','.join(list(role))) - return HttpResponse('dev,sa') + return HttpResponse(','.join([i.name for i in role])) + return HttpResponse('error') @require_role() diff --git a/run_websocket.py b/run_websocket.py index 27420b4ea..58e9e796a 100644 --- a/run_websocket.py +++ b/run_websocket.py @@ -57,15 +57,13 @@ def require_auth(func): uid = session.get_decoded().get('_auth_user_id') user = User.objects.filter(id=uid) asset_id = int(request.get_argument('id', 9999)) - + print asset_id asset = Asset.objects.filter(id=asset_id) if asset: asset = asset[0] request.asset = asset - role = user_have_perm(user, asset) - request.role = role else: - role = '' + request.close() if user: user = user[0] @@ -247,6 +245,7 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler): if role.name == role_name: login_role = role break + print login_role if not login_role: print "no role" self.close() diff --git a/templates/jasset/asset_list.html b/templates/jasset/asset_list.html index eb37d5030..d684e7c41 100644 --- a/templates/jasset/asset_list.html +++ b/templates/jasset/asset_list.html @@ -170,8 +170,8 @@ } }); - $('.conn').click(function(evt){ - var url='/jlog/get_role_name/?id' + $(this).attr('value'); + $('.conn').click(function(){ + var url='/jlog/get_role_name/?id=' + $(this).attr('value'); var href = $(this).attr('href'); var new_url = '/jlog/web_terminal/?id=' + $(this).attr('value') + '&role='; $.ajax({ @@ -179,10 +179,11 @@ url: url, data: {}, success: function(data){ + console.log(data); var dataArray = data.split(','); - if (dataArray.length == 1){ + if (dataArray.length == 1 && data != 'error'){ window.open(new_url + data, '播放', 'height=400, width=600, top=89px, left=99px,toolbar=no,menubar=no,scrollbars=auto,resizeable=no,location=no,status=no'); - } else if (dataArray.length == 0){ + } else if (dataArray.length == '1' && data == 'error'){ layer.alert('没有授权角色') } else { aUrl = ''; @@ -195,7 +196,6 @@ closeBtn: 0 }) } - } }); return false @@ -204,7 +204,7 @@ function windowOpen(aTab){ var new_url = aTab.href; - window.open(new_url, '播放', 'height=400, width=600, top=89px, left=99px,toolbar=no,menubar=no,scrollbars=auto,resizeable=no,location=no,status=no'); + window.open(new_url, '', 'height=400, width=600, top=89px, left=99px,toolbar=no,menubar=no,scrollbars=auto,resizeable=no,location=no,status=no'); return false } From a7a030feddda9a24c128d817e94bd4e7441ee392 Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 23 Nov 2015 23:07:58 +0800 Subject: [PATCH 7/8] fix bug --- jumpserver/context_processors.py | 8 +- run_websocket.py | 130 +++++++++++++++++-------------- templates/jasset/asset_list.html | 4 +- templates/jlog/log_online.html | 20 ++--- 4 files changed, 81 insertions(+), 81 deletions(-) diff --git a/jumpserver/context_processors.py b/jumpserver/context_processors.py index 35c656c25..e84cc60ec 100644 --- a/jumpserver/context_processors.py +++ b/jumpserver/context_processors.py @@ -5,16 +5,12 @@ from jumpserver.api import * def name_proc(request): user_id = request.user.id - # role_id = request.session.get('role_id') - role_id = {'SU':2,'GA':1,'CU':0}.get(request.user.role,0) - # if role_id == 2: + role_id = {'SU': 2, 'GA': 1, 'CU': 0}.get(request.user.role, 0) + # role_id = 'SU' user_total_num = User.objects.all().count() user_active_num = User.objects.filter().count() host_total_num = Asset.objects.all().count() host_active_num = Asset.objects.filter(is_active=True).count() - # else: - # pass - request.session.set_expiry(3600) info_dic = {'session_user_id': user_id, diff --git a/run_websocket.py b/run_websocket.py index 58e9e796a..6963c1701 100644 --- a/run_websocket.py +++ b/run_websocket.py @@ -7,6 +7,7 @@ import os import sys import os.path import threading +import datetime import urllib import tornado.ioloop @@ -22,7 +23,7 @@ from tornado.options import define, options from pyinotify import WatchManager, Notifier, ProcessEvent, IN_DELETE, IN_CREATE, IN_MODIFY, AsyncNotifier import select -from connect import Tty, User, Asset, PermRole +from connect import Tty, User, Asset, PermRole, logger, get_object from connect import TtyLog, Log, Session, user_have_perm try: @@ -35,45 +36,49 @@ define("port", default=3000, help="run on the given port", type=int) define("host", default='0.0.0.0', help="run port on", type=str) -def require_auth(func): - def _deco(request, *args, **kwargs): - if request.get_cookie('sessionid'): - session_key = request.get_cookie('sessionid') - else: - session_key = request.get_secure_cookie('sessionid') +def require_auth(role='user'): + def _deco(func): + def _deco(request, *args, **kwargs): + if request.get_cookie('sessionid'): + session_key = request.get_cookie('sessionid') + else: + session_key = request.get_secure_cookie('sessionid') - print "session: " + session_key + logger.debug('Websocket: session_key: ' + session_key) - if not session_key: - print('Auth Failed') + if session_key: + session = get_object(Session, session_key=session_key) + if session and datetime.datetime.now() > session.expire_date: + user_id = session.get_decoded().get('_auth_user_id') + user = get_object(User, id=user_id) + if user: + logger.debug('Websocket: user [ %s ] request websocket' % user.username) + request.user = user + if role == 'admin': + if user.role in ['SU', 'GA']: + return func(request, *args, **kwargs) + logger.debug('Websocket: user [ %s ] is not admin.' % user.username) + else: + return func(request, *args, **kwargs) request.close() - - session = Session.objects.filter(session_key=session_key) - if not session: - print('Auth Failed') - request.close() - else: - session = session[0] - uid = session.get_decoded().get('_auth_user_id') - user = User.objects.filter(id=uid) - asset_id = int(request.get_argument('id', 9999)) - print asset_id - asset = Asset.objects.filter(id=asset_id) - if asset: - asset = asset[0] - request.asset = asset - else: - request.close() - - if user: - user = user[0] - request.user = user - - else: - print("No session user.") - request.close() - - return func(request, *args, **kwargs) + logger.warning('Websocket: Request auth failed.') + # asset_id = int(request.get_argument('id', 9999)) + # print asset_id + # asset = Asset.objects.filter(id=asset_id) + # if asset: + # asset = asset[0] + # request.asset = asset + # else: + # request.close() + # + # if user: + # user = user[0] + # request.user = user + # + # else: + # print("No session user.") + # request.close() + return _deco return _deco @@ -109,10 +114,10 @@ def file_monitor(path='.', client=None): notifier = AsyncNotifier(wm, EventHandler(client)) wm.add_watch(path, mask, auto_add=True, rec=True) if not os.path.isfile(path): - print "You should monitor a file" + logger.debug("File %s does not exist." % path) sys.exit(3) else: - print "now starting monitor %s." % path + logger.debug("Now starting monitor file %s." % path) global f f = open(path, 'r') st_size = os.stat(path)[6] @@ -158,7 +163,7 @@ class MonitorHandler(tornado.websocket.WebSocketHandler): def check_origin(self, origin): return True - @require_auth + @require_auth('admin') def open(self): # 获取监控的path self.file_path = self.get_argument('file_path', '') @@ -180,7 +185,8 @@ class MonitorHandler(tornado.websocket.WebSocketHandler): MonitorHandler.clients.remove(self) MonitorHandler.threads.remove(MonitorHandler.threads[client_index]) - print len(MonitorHandler.threads), len(MonitorHandler.clients) + logger.debug("Websocket: Monitor client num: %s, thread num: %s" % (len(MonitorHandler.clients), + len(MonitorHandler.threads))) def on_message(self, message): # 监控日志,发生变动发向客户端 @@ -190,10 +196,13 @@ class MonitorHandler(tornado.websocket.WebSocketHandler): # 客户端主动关闭 # self.close() - print "Close websocket." - client_index = MonitorHandler.clients.index(self) - MonitorHandler.clients.remove(self) - MonitorHandler.threads.remove(MonitorHandler.threads[client_index]) + logger.debug("Websocket: Monitor client close request") + try: + client_index = MonitorHandler.clients.index(self) + MonitorHandler.clients.remove(self) + MonitorHandler.threads.remove(MonitorHandler.threads[client_index]) + except ValueError: + pass class WebTty(Tty): @@ -206,6 +215,7 @@ class WebTty(Tty): class WebTerminalKillHandler(tornado.web.RequestHandler): + @require_auth('admin') def get(self): ws_id = self.get_argument('id') Log.objects.filter(id=ws_id).update(is_finished=True) @@ -228,7 +238,6 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler): self.log_time_f = None self.log = None self.id = 0 - self.asset = None self.user = None super(WebTerminalHandler, self).__init__(*args, **kwargs) @@ -237,19 +246,22 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler): @require_auth def open(self): - print self.user, self.asset - role_name = self.get_argument('role', 'root') - roles = user_have_perm(self.user, self.asset) - login_role = '' - for role in roles: - if role.name == role_name: - login_role = role - break - print login_role - if not login_role: - print "no role" - self.close() - return + role_name = self.get_argument('role', 'sb') + asset_id = self.get_argument('id', 9999) + asset = get_object(Asset, id=asset_id) + if asset: + roles = user_have_perm(self.user, asset) + login_role = '' + for role in roles: + if role.name == role_name: + login_role = role + break + if not login_role: + logger.warning('Websocket: Not that Role %s for Host: %s User: %s ' % (role_name, asset.name, + self.user.username)) + self.close() + return + logger.debug('Websocket: request web terminal Host: %s User: %s Role: %s' % ()) # Todo: 判断 self.term = WebTty(self.user, self.asset, login_role) self.term.get_connection() diff --git a/templates/jasset/asset_list.html b/templates/jasset/asset_list.html index d684e7c41..e6a12567d 100644 --- a/templates/jasset/asset_list.html +++ b/templates/jasset/asset_list.html @@ -179,10 +179,10 @@ url: url, data: {}, success: function(data){ - console.log(data); var dataArray = data.split(','); if (dataArray.length == 1 && data != 'error'){ - window.open(new_url + data, '播放', 'height=400, width=600, top=89px, left=99px,toolbar=no,menubar=no,scrollbars=auto,resizeable=no,location=no,status=no'); + console.log('one'); + window.open(new_url + data, '', 'height=400, width=600, top=89px, left=99px,toolbar=no,menubar=no,scrollbars=auto,resizeable=no,location=no,status=no'); } else if (dataArray.length == '1' && data == 'error'){ layer.alert('没有授权角色') } else { diff --git a/templates/jlog/log_online.html b/templates/jlog/log_online.html index 96d8a9d07..42ea11a38 100644 --- a/templates/jlog/log_online.html +++ b/templates/jlog/log_online.html @@ -79,11 +79,9 @@ 用户名 登录主机 来源IP - {% ifnotequal session_role_id 0 %} - 统计命令 - 实时监控 - 阻断 - {% endifnotequal %} + 统计命令 + 实时监控 + 阻断 登录时间 @@ -94,11 +92,9 @@ {{ post.user }} {{ post.host }} {{ post.remote_ip }} - {% ifnotequal session_role_id 0 %} - 命令统计 - 监控 - - {% endifnotequal %} + 命令统计 + 监控 + {{ post.start_time|date:"Y-m-d H:i:s" }} {% endfor %} @@ -188,10 +184,6 @@ }}); return false; }); - - $('#test_connect').click(function(){ - window.open('/jlog/web_terminal/?asset_name="hello', '播放', 'height=400, width=600, top=89px, left=99px,toolbar=no,menubar=no,scrollbars=auto,resizeable=no,location=no,status=no'); - }); }); {# function log_search(){#} From 17ccac92ee927d05883366afbf768a52c29a5c53 Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 24 Nov 2015 11:01:54 +0800 Subject: [PATCH 8/8] =?UTF-8?q?fix=20=E5=8A=A0=E5=AF=86bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jlog/views.py | 6 ++++-- jumpserver/api.py | 2 +- run_websocket.py | 10 +++++++--- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/jlog/views.py b/jlog/views.py index 82a4891e7..472f2c3b7 100644 --- a/jlog/views.py +++ b/jlog/views.py @@ -104,6 +104,7 @@ def log_record(request): return HttpResponse('无日志记录!') +@require_role('user') def get_role_name(request): asset_id = request.GET.get('id', 9999) asset = get_object(Asset, id=asset_id) @@ -113,9 +114,10 @@ def get_role_name(request): return HttpResponse('error') -@require_role() +@require_role('user') def web_terminal(request): asset_id = request.GET.get('id') - web_terminal_uri = 'ws://%s/terminal?id=%s&role=dev' % (WEB_SOCKET_HOST, asset_id) + role_name = request.GET.get('role') + web_terminal_uri = 'ws://%s/terminal?id=%s&role=%s' % (WEB_SOCKET_HOST, asset_id, role_name) return render_to_response('jlog/web_terminal.html', locals()) diff --git a/jumpserver/api.py b/jumpserver/api.py index cbf7eebc8..7e2a0d0ef 100644 --- a/jumpserver/api.py +++ b/jumpserver/api.py @@ -59,7 +59,7 @@ def get_asset_info(asset): else: info['port'] = asset.port info['username'] = asset.username - info['password'] = asset.password + info['password'] = CRYPTOR.decrypt(asset.password) return info diff --git a/run_websocket.py b/run_websocket.py index 6963c1701..02b132f2d 100644 --- a/run_websocket.py +++ b/run_websocket.py @@ -257,12 +257,16 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler): login_role = role break if not login_role: - logger.warning('Websocket: Not that Role %s for Host: %s User: %s ' % (role_name, asset.name, + logger.warning('Websocket: Not that Role %s for Host: %s User: %s ' % (role_name, asset.hostname, self.user.username)) self.close() return - logger.debug('Websocket: request web terminal Host: %s User: %s Role: %s' % ()) - # Todo: 判断 + else: + logger.warning('Websocket: No that Host: %s User: %s ' % (asset_id, self.user.username)) + self.close() + return + logger.debug('Websocket: request web terminal Host: %s User: %s Role: %s' % (asset.hostname, self.user.username, + login_role.name)) self.term = WebTty(self.user, self.asset, login_role) self.term.get_connection() self.term.channel = self.term.ssh.invoke_shell(term='xterm')