diff --git a/.idea/.name b/.idea/.name deleted file mode 100644 index 9d00477b6..000000000 --- a/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -jumpserver \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml deleted file mode 100644 index 7c62b52a1..000000000 --- a/.idea/encodings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 8766f794e..000000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml deleted file mode 100644 index 3b312839b..000000000 --- a/.idea/inspectionProfiles/profiles_settings.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/jumpserver.iml b/.idea/jumpserver.iml deleted file mode 100644 index 9dcd47829..000000000 --- a/.idea/jumpserver.iml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 0e219b1ba..000000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index c0087f33b..000000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml deleted file mode 100644 index 0d5175ca0..000000000 --- a/.idea/scopes/scope_settings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index ab55cf163..000000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/.idea/workspace.xml b/.idea/workspace.xml deleted file mode 100644 index 16dd6d723..000000000 --- a/.idea/workspace.xml +++ /dev/null @@ -1,793 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1410786645479 - 1410786645479 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/jumpserver.py b/jumpserver.py index a86a20478..2c38a7371 100755 --- a/jumpserver.py +++ b/jumpserver.py @@ -18,9 +18,7 @@ import paramiko import pxssh import pexpect -cur_dir = os.path.dirname(__file__) -if not cur_dir: - cur_dir = "./" +cur_dir = os.path.abspath(os.path.dirname(__file__)) sys.path.append('%s/webroot/AutoSa/' % cur_dir) os.environ['DJANGO_SETTINGS_MODULE'] = 'AutoSa.settings' diff --git a/scripts/requirements.txt b/scripts/requirements.txt index 6a7e06134..2af0ae0e4 100644 --- a/scripts/requirements.txt +++ b/scripts/requirements.txt @@ -1,14 +1,8 @@ pexpect==3.3 -django-socketio==0.3.9 -gevent-socketio==0.2.1 sphinx-me==0.3 django==1.7.1 -gevent-websocket==0.9.3 -gevent==1.0.1 -greenlet==0.4.5 python-ldap==2.4.18 paramiko==1.15.1 pycrypto==2.6.1 ecdsa>=0.11 MySQL-python==1.2.5 -python-ldap==2.4.18 diff --git a/webroot/AutoSa/Assets/models.py b/webroot/AutoSa/Assets/models.py index 50dbe37c1..52c6f05ac 100644 --- a/webroot/AutoSa/Assets/models.py +++ b/webroot/AutoSa/Assets/models.py @@ -2,11 +2,18 @@ from django.db import models from UserManage.models import User +class IDC(models.Model): + name = models.CharField(max_length=20) + + def __unicode__(self): + return self.name + + class Assets(models.Model): id = models.AutoField(primary_key=True) ip = models.CharField(max_length=20) port = models.IntegerField(max_length=5) - idc = models.CharField(max_length=50) + idc = models.ForeignKey(IDC) comment = models.CharField(max_length=100, blank=True, null=True) def __unicode__(self): @@ -15,4 +22,6 @@ class Assets(models.Model): class AssetsUser(models.Model): uid = models.ForeignKey(User) - aid = models.ForeignKey(Assets) \ No newline at end of file + aid = models.ForeignKey(Assets) + + diff --git a/webroot/AutoSa/AutoSa/urls.py b/webroot/AutoSa/AutoSa/urls.py index d0bcec57d..f6ca92c95 100644 --- a/webroot/AutoSa/AutoSa/urls.py +++ b/webroot/AutoSa/AutoSa/urls.py @@ -20,6 +20,9 @@ urlpatterns = patterns('', (r'^showGroup/$', views.showGroup), (r'^addGroup/$', views.addGroup), (r'^chgGroup/$', views.chgGroup), + (r'^showIDC/$', views.showIDC), + (r'^addIDC/$', views.addIDC), + (r'^chgIDC/$', views.chgIDC), (r'^showSudo/$', views.showSudo), (r'^chgSudo/$', views.chgSudo), (r'^showAssets/$', views.showAssets), diff --git a/webroot/AutoSa/AutoSa/views.py b/webroot/AutoSa/AutoSa/views.py index ca765bbd2..6f1d371c9 100644 --- a/webroot/AutoSa/AutoSa/views.py +++ b/webroot/AutoSa/AutoSa/views.py @@ -5,7 +5,7 @@ from django.template import RequestContext from django.shortcuts import render_to_response from django.http import HttpResponseRedirect from UserManage.models import User, Group, Logs, Pid -from Assets.models import Assets, AssetsUser +from Assets.models import Assets, AssetsUser, IDC import subprocess from Crypto.Cipher import AES from binascii import b2a_hex, a2b_hex @@ -290,7 +290,11 @@ def downKey(request): username = request.GET.get('username') filename = '%s/%s' % (rsa_dir, username) - f = open(filename) + try: + f = open(filename) + except IOError: + error = u'密钥文件不存在' + return render_to_response('info.html', {'error': error}) data = f.read() f.close() response = HttpResponse(data, content_type='application/octet-stream') @@ -320,9 +324,21 @@ def showUser(request): error = '' if is_super_user(request): - users = User.objects.all() + users_all = User.objects.all() else: - users = group_member(request.session.get('username')) + users_all = group_member(request.session.get('username')) + + paginator = Paginator(users_all, 20) + + try: + page = int(request.GET.get('page', 1)) + except ValueError: + page = 1 + + try: + users = paginator.page(page) + except (EmptyPage, InvalidPage): + users = paginator.page(paginator.num_pages) if request.method == 'POST': selected_user = request.REQUEST.getlist('selected') @@ -376,7 +392,9 @@ def addUser(request): if request.method == 'POST': form = UserAddForm(request.POST) - if form.is_valid(): + if not form.is_valid(): + return HttpResponse('error') + else: user = form.cleaned_data username = user['username'] password = user['password'] @@ -584,13 +602,18 @@ def chgGroup(request): error = '' msg = '' if request.method == 'GET': - group_id = request.GET.get('id') - group = Group.objects.get(id=group_id) + group_id = request.GET.get('id', None) + if group_id: + group = Group.objects.get(id=group_id) + else: + return HttpResponseRedirect('/showGroup/') else: group_id = request.POST.get('id') group_name = request.POST.get('name') + if not group_name: error = u'不能为空' + return render_to_response('info.html', {'error': error}) else: group = Group.objects.get(id=group_id) group.name = group_name @@ -601,6 +624,67 @@ def chgGroup(request): context_instance=RequestContext(request)) +@superuser_required +def showIDC(request): + error = '' + msg = '' + idcs = IDC.objects.all() + + if request.method == 'POST': + selected_idc = request.REQUEST.getlist('selected') + if selected_idc: + for idc_id in selected_idc: + idc = IDC.objects.get(id=idc_id) + idc.delete() + msg = '删除成功' + + return render_to_response('showIDC.html', + {'idcs': idcs, 'error': error, 'msg': msg, 'asset_menu': 'active'}, + context_instance=RequestContext(request)) + + +@superuser_required +def chgIDC(request): + error = '' + msg = '' + if request.method == 'GET': + idc_id = request.GET.get('id', None) + if not idc_id: + return HttpResponseRedirect('/showIDC/') + else: + idc = IDC.objects.get(id=idc_id) + else: + idc_id = request.POST.get('id') + idc_name = request.POST.get('name') + if not idc_name: + error = u'不能为空' + return render_to_response('info.html', {'error': error}) + else: + idc = Group.objects.get(id=idc_id) + idc.name = idc_name + idc.save() + msg = u'修改成功' + + return render_to_response('chgGroup.html', {'idc': idc, 'error': error, 'msg': msg, 'asset_menu': 'active'}, + context_instance=RequestContext(request)) + + +@superuser_required +def addIDC(request): + error = '' + msg = '' + if request.method == 'POST': + idc_name = request.POST.get('name') + if idc_name: + idc = IDC(name=idc_name) + idc.save() + msg = u'%s IDC添加成功' % idc_name + else: + error = u'不能为空' + return render_to_response('addIDC.html', + {'error': error, 'msg': msg, 'user_menu': 'active'}, + context_instance=RequestContext(request)) + @admin_required def showSudo(request): if request.method == 'GET': @@ -680,13 +764,25 @@ def showAssets(request): """查看服务器""" info = '' if request.session.get('admin') < 2: - assets = [] + assets_all = [] username = request.session.get('username') user = User.objects.get(username=username) for asset in user.assetsuser_set.all().order_by('ip'): - assets.append(asset.aid) + assets_all.append(asset.aid) else: - assets = Assets.objects.all().order_by('ip') + assets_all = Assets.objects.all().order_by('ip') + paginator = Paginator(assets_all, 20) + + try: + page = int(request.GET.get('page', 1)) + except ValueError: + page = 1 + + try: + assets = paginator.page(page) + except (EmptyPage, InvalidPage): + assets = paginator.page(paginator.num_pages) + if request.method == 'POST': if request.session.get('admin') < 2: return HttpResponseRedirect('/showAssets/') @@ -704,12 +800,15 @@ def addAssets(request): """添加服务器""" error = '' msg = '' + idcs = IDC.objects.all() if request.method == 'POST': ip = request.POST.get('ip') port = request.POST.get('port') idc = request.POST.get('idc') comment = request.POST.get('comment') + idc = IDC.objects.get(id=idc) + if '' in (ip, port): error = '带*号内容不能为空。' elif Assets.objects.filter(ip=ip): @@ -719,7 +818,7 @@ def addAssets(request): asset.save() msg = u'%s 添加成功' % ip - return render_to_response('addAssets.html', {'msg': msg, 'error': error, 'asset_menu': 'active'}, + return render_to_response('addAssets.html', {'msg': msg, 'error': error, 'idcs': idcs, 'asset_menu': 'active'}, context_instance=RequestContext(request)) @@ -727,9 +826,21 @@ def addAssets(request): def showPerm(request): """查看权限""" if is_super_user(request): - users = User.objects.all() + users_all = User.objects.all() else: - users = group_member(request.session.get('username')) + users_all = group_member(request.session.get('username')) + + paginator = Paginator(users_all, 20) + + try: + page = int(request.GET.get('page', 1)) + except ValueError: + page = 1 + + try: + users = paginator.page(page) + except (EmptyPage, InvalidPage): + users = paginator.page(paginator.num_pages) if request.method == 'POST': assets_del = request.REQUEST.getlist('selected') @@ -737,7 +848,7 @@ def showPerm(request): user = User.objects.get(username=username) for asset_id in assets_del: - asset = Assets.objects.get(id=asset_id) + asset = Assets.objects.get(id=int(asset_id)) asset_user_del = AssetsUser.objects.get(uid=user, aid=asset) asset_user_del.delete() return HttpResponseRedirect('/showPerm/?username=%s' % username) @@ -820,7 +931,7 @@ def chgPass(request): if not is_admin_role(request): oldpass = request.POST.get('oldpass') - if oldpass != user.password: + if md5_crypt(oldpass) != user.password: error = '原来密码不正确' if password != password_again: @@ -829,7 +940,7 @@ def chgPass(request): if error: return render_to_response('info.html', {'error': error}) - user.password = password + user.password = md5_crypt(password) user.save() return render_to_response('info.html', {'msg': '修改密码成功'}) @@ -857,10 +968,11 @@ def chgKey(request): user = User.objects.get(username=username) password = request.POST.get('password') password_again = request.POST.get('password_again') + jm = PyCrypt(key) if not is_admin_role(request): oldpass = request.POST.get('oldpass') - if oldpass != user.key_pass: + if jm.encrypt(oldpass) != user.key_pass: error = '原来密码不正确' if password != password_again: @@ -873,12 +985,11 @@ def chgKey(request): return render_to_response('info.html', {'error': error}) keyfile = '%s/%s' % (rsa_dir, username) - jm = PyCrypt(key) ret = bash('ssh-keygen -p -P %s -N %s -f %s' % (jm.decrypt(user.key_pass), password, keyfile)) if ret != 0: error = '更改私钥密码错误' return render_to_response('info.html', {'error': error}) - user.key_pass = password + user.key_pass = jm.encrypt(password) user.save() return render_to_response('info.html', {'msg': '修改密码成功'}) @@ -962,7 +1073,7 @@ def downFile(request): (time.strftime('%Y/%m/%d %H:%M:%S'), username, host, path)) f.close() wrapper = FileWrapper(open(download_file)) - response = HttpResponse(wrapper, mimetype='application/octet-stream') + response = HttpResponse(wrapper, content_type='application/octet-stream') response['Content-Disposition'] = 'attachment; filename=%s' % os.path.basename(path) return response @@ -975,7 +1086,7 @@ def downFile(request): def logView(request): thirtyDayAgo = (datetime.datetime.now() - datetime.timedelta(30)) thirtyDayAgoStamp = int(time.mktime(thirtyDayAgo.timetuple())) - logs_all = Logs.objects.filter(start_time__gt=thirtyDayAgoStamp) + logs_all = Logs.objects.filter(start_time__gt=thirtyDayAgoStamp).order_by("-id") paginator = Paginator(logs_all, 20) try: @@ -1015,7 +1126,7 @@ def killSession(request): if pid: pid = pid[0] os.kill(pid.cpid, 9) - return HttpResponse('ok') + return render_to_response('info.html', {'msg': u'结束会话成功,返回中.'}) diff --git a/webroot/AutoSa/UserManage/forms.py b/webroot/AutoSa/UserManage/forms.py index a41222291..a5597a39c 100644 --- a/webroot/AutoSa/UserManage/forms.py +++ b/webroot/AutoSa/UserManage/forms.py @@ -39,8 +39,10 @@ class UserAddForm(forms.Form): return password_again def clean_key_pass_again(self): - key_pass = self.cleaned_data['key_pass'] - key_pass_again = self.cleaned_data['key_pass_again'] + key_pass = self.data['key_pass'] + key_pass_again = self.data['key_pass_again'] if key_pass != key_pass_again: raise forms.ValidationError('Key Password input twice not match. ') + if len(key_pass) < 6: + raise forms.ValidationError('Key Password input twice not match. ') return key_pass_again \ No newline at end of file diff --git a/webroot/AutoSa/log_handler.py b/webroot/AutoSa/log_handler.py index 769ac65d3..f84ab7bbe 100755 --- a/webroot/AutoSa/log_handler.py +++ b/webroot/AutoSa/log_handler.py @@ -24,7 +24,7 @@ def log_hanler(logid): ret2 = os.system('cat %s | grep "\[.*@.*\][\$\#]" >> %s.his' % (filename, filename)) ret3 = os.system('cat %s | grep "EndTime" >> %s.his' % (filename, filename)) if (ret1 + ret2 + ret3) == 0: - print 'Handler % ok.' % filename + print 'Handler %s ok.' % filename def set_finish(id): diff --git a/webroot/AutoSa/runserver b/webroot/AutoSa/runserver index e716b1845..2bee5c224 100755 --- a/webroot/AutoSa/runserver +++ b/webroot/AutoSa/runserver @@ -1,3 +1,4 @@ #!/bin/bash -./manage.py runserver 0.0.0.0:80 +./manage.py runserver 0.0.0.0:80 &> access.log & +./log_handler.py &> handler.log & diff --git a/webroot/AutoSa/static/js/main.js b/webroot/AutoSa/static/js/main.js index 85e79246a..6258f56ab 100644 --- a/webroot/AutoSa/static/js/main.js +++ b/webroot/AutoSa/static/js/main.js @@ -27,19 +27,39 @@ $.fn.webSocket = function(opt){ return new Date().getTime()+""+Math.floor(Math.random()*899+100); }; - var init = function(){ - message.id = genUid(); - message.filename = $this.attr('filename'); + var init = function(e){ var socket = io.connect('ws://172.10.10.9:3000'); - //告诉服务器端有用户登录 - socket.emit('login', {userid:message.id, filename:message.filename}); - socket.on('message',function(obj){ - window.console.log(obj.content); - }); + var node = $(e.target); + message.id = genUid(); + message.filename = node.attr('filename'); + BootstrapDialog.show({message:function(){ + var escapeString = function (html){ + var elem = document.createElement('div') + var txt = document.createTextNode(html) + elem.appendChild(txt) + return elem.innerHTML; + } + var tag = $('
'); + //告诉服务器端有用户登录 + socket.emit('login', {userid:message.id, filename:message.filename}); + socket.on('message',function(obj){ + //去除log中的颜色控制字符 + var regx = /\x1B\[([0-9]{1,3}((;[0-9]{1,3})*)?)?[m|K]/g; + tag.append('

'+escapeString(obj.content.replace(regx,''))+'

'); + }); + return tag[0]; + } , + title:'日志', + onhide:function(){ + socket.emit('disconnect'); + }}); } - $this.on("click",function(){ - init(); + + + $this.on("click",function(e){ + init(e); + return false; }); } diff --git a/webroot/AutoSa/templates/addAssets.html b/webroot/AutoSa/templates/addAssets.html index f230b7b7a..be1100757 100644 --- a/webroot/AutoSa/templates/addAssets.html +++ b/webroot/AutoSa/templates/addAssets.html @@ -28,8 +28,17 @@
- +
+
+ 添加IDC + 删除IDC +
+
diff --git a/webroot/AutoSa/templates/addIDC.html b/webroot/AutoSa/templates/addIDC.html new file mode 100644 index 000000000..59f018405 --- /dev/null +++ b/webroot/AutoSa/templates/addIDC.html @@ -0,0 +1,31 @@ +{% extends 'base.html' %} +{% block content %} +
+
+ 添加IDC + {% if error %} +
+ {{ error }} +
+ {% endif %} + {% if msg %} +
+ {{ msg }} +
+ {% endif %} +
+ +
+ +
+ +
+ +
+
+ +
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/webroot/AutoSa/templates/addPerm.html b/webroot/AutoSa/templates/addPerm.html index 2c28bd213..ff505b54a 100644 --- a/webroot/AutoSa/templates/addPerm.html +++ b/webroot/AutoSa/templates/addPerm.html @@ -26,7 +26,7 @@ {% endfor %} - + {% endblock %} %} \ No newline at end of file diff --git a/webroot/AutoSa/templates/base.html b/webroot/AutoSa/templates/base.html index 2b4b3b3bc..9305e4c47 100644 --- a/webroot/AutoSa/templates/base.html +++ b/webroot/AutoSa/templates/base.html @@ -2,8 +2,8 @@ -运维管理系统 - +Jumpserver + + {% if not admin %}