jumpserver/jumpserver/views.py

346 lines
13 KiB
Python

# coding: utf-8
from __future__ import division
import uuid
import urllib
from django.db.models import Count
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.http import HttpResponseNotFound
from django.http import HttpResponse
# from jperm.models import Apply
import paramiko
from jumpserver.api import *
from jumpserver.models import Setting
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from jlog.models import Log, FileLog
from jperm.perm_api import get_group_user_perm, gen_resource
from jasset.models import Asset, IDC
from jperm.ansible_api import MyRunner
def getDaysByNum(num):
"""
输出格式:([datetime.date(2015, 11, 6), datetime.date(2015, 11, 8)], ['11-06', '11-08'])
"""
today = datetime.date.today()
oneday = datetime.timedelta(days=1)
date_li, date_str = [], []
for i in range(0, num):
today = today-oneday
date_li.append(today)
date_str.append(str(today)[5:10])
date_li.reverse()
date_str.reverse()
return date_li, date_str
def get_data(x, y, z):
pass
def get_data_by_day(date_li, item):
data_li = []
for d in date_li:
logs = Log.objects.filter(start_time__year=d.year,
start_time__month=d.month,
start_time__day=d.day)
if item == 'user':
data_li.append(set([log.user for log in logs]))
elif item == 'asset':
data_li.append(set([log.host for log in logs]))
elif item == 'login':
data_li.append(logs)
else:
pass
return data_li
def get_count_by_day(date_li, item):
data_li = get_data_by_day(date_li, item)
data_count_li = []
for data in data_li:
data_count_li.append(len(data))
return data_count_li
def get_count_by_date(date_li, item):
data_li = get_data_by_day(date_li, item)
data_count_tmp = []
for data in data_li:
data_count_tmp.extend(list(data))
return len(set(data_count_tmp))
@require_role(role='user')
def index_cu(request):
username = request.user.username
return HttpResponseRedirect('/juser/user_detail/')
@require_role(role='user')
def index(request):
li_date, li_str = getDaysByNum(7)
today = datetime.datetime.now().day
from_week = datetime.datetime.now() - datetime.timedelta(days=7)
if is_role_request(request, 'user'):
return index_cu(request)
elif is_role_request(request, 'super'):
# dashboard 显示汇总
users = User.objects.all()
hosts = Asset.objects.all()
online = Log.objects.filter(is_finished=0)
online_host = online.values('host').distinct()
online_user = online.values('user').distinct()
active_users = User.objects.filter(is_active=1)
active_hosts = Asset.objects.filter(is_active=1)
# 一个月历史汇总
date_li, date_str = getDaysByNum(30)
date_month = repr(date_str)
active_user_per_month = str(get_count_by_day(date_li, 'user'))
active_asset_per_month = str(get_count_by_day(date_li, 'asset'))
active_login_per_month = str(get_count_by_day(date_li, 'login'))
# 活跃用户资产图
active_user_month = get_count_by_date(date_li, 'user')
disabled_user_count = len(users.filter(is_active=False))
inactive_user_month = len(users) - active_user_month
active_asset_month = get_count_by_date(date_li, 'asset')
disabled_asset_count = len(hosts.filter(is_active=False)) if hosts.filter(is_active=False) else 0
inactive_asset_month = len(hosts) - active_asset_month if len(hosts) > active_asset_month else 0
# 一周top10用户和主机
week_data = Log.objects.filter(start_time__range=[from_week, datetime.datetime.now()])
user_top_ten = week_data.values('user').annotate(times=Count('user')).order_by('-times')[:10]
host_top_ten = week_data.values('host').annotate(times=Count('host')).order_by('-times')[:10]
for user_info in user_top_ten:
username = user_info.get('user')
last = Log.objects.filter(user=username).latest('start_time')
user_info['last'] = last
for host_info in host_top_ten:
host = host_info.get('host')
last = Log.objects.filter(host=host).latest('start_time')
host_info['last'] = last
# 一周top5
week_users = week_data.values('user').distinct().count()
week_hosts = week_data.count()
user_top_five = week_data.values('user').annotate(times=Count('user')).order_by('-times')[:5]
color = ['label-success', 'label-info', 'label-primary', 'label-default', 'label-warnning']
# 最后10次权限申请
# perm apply latest 10
# perm_apply_10 = Apply.objects.order_by('-date_add')[:10]
# 最后10次登陆
login_10 = Log.objects.order_by('-start_time')[:10]
login_more_10 = Log.objects.order_by('-start_time')[10:21]
return render_to_response('index.html', locals(), context_instance=RequestContext(request))
def skin_config(request):
return render_to_response('skin_config.html')
def is_latest():
node = uuid.getnode()
jsn = uuid.UUID(int=node).hex[-12:]
with open(os.path.join(BASE_DIR, 'version')) as f:
current_version = f.read()
lastest_version = urllib.urlopen('http://www.jumpserver.org/lastest_version.html?jsn=%s' % jsn).read().strip()
if current_version != lastest_version:
pass
@defend_attack
def Login(request):
"""登录界面"""
error = ''
if request.user.is_authenticated():
return HttpResponseRedirect('/')
if request.method == 'GET':
return render_to_response('login.html')
else:
username = request.POST.get('username')
password = request.POST.get('password')
if username and password:
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
# c = {}
# c.update(csrf(request))
# request.session['csrf_token'] = str(c.get('csrf_token'))
# user_filter = User.objects.filter(username=username)
# if user_filter:
# user = user_filter[0]
# if PyCrypt.md5_crypt(password) == user.password:
# request.session['user_id'] = user.id
# user_filter.update(last_login=datetime.datetime.now())
if user.role == 'SU':
request.session['role_id'] = 2
elif user.role == 'GA':
request.session['role_id'] = 1
else:
request.session['role_id'] = 0
return HttpResponseRedirect(request.session.get('pre_url', '/'))
# response.set_cookie('username', username, expires=604800)
# response.set_cookie('seed', PyCrypt.md5_crypt(password), expires=604800)
# return response
else:
error = '用户未激活'
else:
error = '用户名或密码错误'
else:
error = '用户名或密码错误'
return render_to_response('login.html', {'error': error})
@require_role('user')
def Logout(request):
logout(request)
return HttpResponseRedirect('/login/')
@require_role('admin')
def setting(request):
header_title, path1 = '项目设置', '设置'
setting_default = get_object(Setting, name='default')
if request.method == "POST":
setting_raw = request.POST.get('setting', '')
if setting_raw == 'default':
username = request.POST.get('username', '')
port = request.POST.get('port', '')
password = request.POST.get('password', '')
private_key = request.POST.get('key', '')
if '' in [username, port]:
return HttpResponse('所填内容不能为空, 且密码和私钥填一个')
else:
private_key_path = os.path.join(BASE_DIR, 'keys/role_keys', 'default', 'default_private_key.pem')
if private_key:
with open(private_key_path, 'w') as f:
f.write(private_key)
os.chmod(private_key_path, 0600)
if setting_default:
if password:
password_encode = CRYPTOR.encrypt(password)
else:
password_encode = password
Setting.objects.filter(name='default').update(field1=username, field2=port,
field3=password_encode,
field4=private_key_path)
else:
password_encode = CRYPTOR.encrypt(password)
setting_r = Setting(name='default', field1=username, field2=port,
field3=password_encode,
field4=private_key_path).save()
msg = "设置成功"
return my_render('setting.html', locals(), request)
@login_required(login_url='/login')
def upload(request):
user = request.user
assets = get_group_user_perm(user).get('asset').keys()
asset_select = []
if request.method == 'POST':
remote_ip = request.META.get('REMOTE_ADDR')
asset_ids = request.POST.getlist('asset_ids', '')
upload_files = request.FILES.getlist('file[]', None)
date_now = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
upload_dir = get_tmp_dir()
# file_dict = {}
for asset_id in asset_ids:
asset_select.append(get_object(Asset, id=asset_id))
if not set(asset_select).issubset(set(assets)):
illegal_asset = set(asset_select).issubset(set(assets))
return HttpResponse('没有权限的服务器 %s' % ','.join([asset.hostname for asset in illegal_asset]))
for upload_file in upload_files:
file_path = '%s/%s' % (upload_dir, upload_file.name)
with open(file_path, 'w') as f:
for chunk in upload_file.chunks():
f.write(chunk)
res = gen_resource({'user': user, 'asset': asset_select})
runner = MyRunner(res)
runner.run('copy', module_args='src=%s dest=%s directory_mode'
% (upload_dir, upload_dir), pattern='*')
ret = runner.results
logger.debug(ret)
FileLog(user=request.user.username, host=' '.join([asset.hostname for asset in asset_select]),
filename=' '.join([f.name for f in upload_files]), type='upload', remote_ip=remote_ip,
result=ret).save()
if ret.get('failed'):
error = u'上传目录: %s <br> 上传失败: [ %s ] <br>上传成功 [ %s ]' % (upload_dir,
', '.join(ret.get('failed').keys()),
', '.join(ret.get('ok').keys()))
return HttpResponse(error, status=500)
msg = u'上传目录: %s <br> 传送成功 [ %s ]' % (upload_dir, ', '.join(ret.get('ok').keys()))
return HttpResponse(msg)
return my_render('upload.html', locals(), request)
@login_required(login_url='/login')
def download(request):
user = request.user
assets = get_group_user_perm(user).get('asset').keys()
asset_select = []
if request.method == 'POST':
remote_ip = request.META.get('REMOTE_ADDR')
asset_ids = request.POST.getlist('asset_ids', '')
file_path = request.POST.get('file_path')
date_now = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
upload_dir = get_tmp_dir()
for asset_id in asset_ids:
asset_select.append(get_object(Asset, id=asset_id))
if not set(asset_select).issubset(set(assets)):
illegal_asset = set(asset_select).issubset(set(assets))
return HttpResponse(u'没有权限的服务器 %s' % ','.join([asset.hostname for asset in illegal_asset]))
res = gen_resource({'user': user, 'asset': asset_select})
runner = MyRunner(res)
runner.run('fetch', module_args='src=%s dest=%s' % (file_path, upload_dir), pattern='*')
FileLog(user=request.user.username, host=' '.join([asset.hostname for asset in asset_select]),
filename=file_path, type='download', remote_ip=remote_ip, result=runner.results).save()
logger.debug(runner.results)
os.chdir('/tmp')
tmp_dir_name = os.path.basename(upload_dir)
tar_file = '%s.tar.gz' % upload_dir
bash('tar czf %s %s' % (tar_file, tmp_dir_name))
f = open(tar_file)
data = f.read()
f.close()
response = HttpResponse(data, content_type='application/octet-stream')
response['Content-Disposition'] = 'attachment; filename=%s' % os.path.basename(tar_file)
return response
return render_to_response('download.html', locals(), context_instance=RequestContext(request))
@login_required(login_url='/login')
def exec_cmd(request):
role = request.GET.get('role')
check_assets = request.GET.get('check_assets', '')
web_terminal_uri = 'ws://%s/exec?role=%s' % (WEB_SOCKET_HOST, role)
return my_render('exec_cmd.html', locals(), request)