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 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- false
-
-
-
-
- 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 @@