diff --git a/connect.py b/connect.py index 7a04c4a17..a91507b14 100755 --- a/connect.py +++ b/connect.py @@ -17,15 +17,15 @@ import getpass import fnmatch import readline from multiprocessing import Pool -from ConfigParser import ConfigParser -from django.core.exceptions import ObjectDoesNotExist + os.environ['DJANGO_SETTINGS_MODULE'] = 'jumpserver.settings' django.setup() from juser.models import User -from jasset.models import AssetAlias + from jlog.models import Log from jumpserver.api import * + try: import termios import tty @@ -57,10 +57,6 @@ def color_print_exit(msg, color='red'): sys.exit() -class ServerError(Exception): - pass - - def get_win_size(): """This function use to get the size of the windows!""" if 'TIOCGWINSZ' in dir(termios): @@ -81,14 +77,6 @@ def set_win_size(sig, data): pass -def get_object(model, **kwargs): - try: - the_object = model.objects.get(**kwargs) - except ObjectDoesNotExist: - raise ServerError('Object get %s failed.' % str(kwargs.values())) - return the_object - - def log_record(username, host): """Logging user command and output.""" connect_log_dir = os.path.join(LOG_DIR, 'connect') @@ -171,20 +159,6 @@ def posix_shell(chan, username, host): print_prompt() -def get_user_host(username): - """Get the hosts of under the user control.""" - hosts_attr = {} - asset_all = user_perm_asset_api(username) - user = User.objects.get(username=username) - for asset in asset_all: - alias = AssetAlias.objects.filter(user=user, host=asset) - if alias and alias[0].alias != '': - hosts_attr[asset.ip] = [asset.id, asset.ip, alias[0].alias] - else: - hosts_attr[asset.ip] = [asset.id, asset.ip, asset.comment] - return hosts_attr - - def get_user_hostgroup(username): """Get the hostgroups of under the user control.""" groups_attr = {} @@ -208,36 +182,6 @@ def get_user_hostgroup_host(username, gid): return hosts_attr -def get_connect_item(username, ip): - - asset = get_object(Asset, ip=ip) - port = asset.port - - if not asset.is_active: - raise ServerError('Host %s is not active.' % ip) - - user = get_object(User, username=username) - - if not user.is_active: - raise ServerError('User %s is not active.' % username) - - login_type_dict = { - 'L': user.ldap_pwd, - } - - if asset.login_type in login_type_dict: - password = CRYPTOR.decrypt(login_type_dict[asset.login_type]) - return username, password, ip, port - - elif asset.login_type == 'M': - username = asset.username - password = CRYPTOR.decrypt(asset.password) - return username, password, ip, port - - else: - raise ServerError('Login type is not in ["L", "M"]') - - def verify_connect(username, part_ip): ip_matched = [] hosts_attr = get_user_host(username) diff --git a/jumpserver/api.py b/jumpserver/api.py index 83be10278..9599ce31c 100644 --- a/jumpserver/api.py +++ b/jumpserver/api.py @@ -11,11 +11,14 @@ import ldap from ldap import modlist import hashlib import datetime +import subprocess from django.core.paginator import Paginator, EmptyPage, InvalidPage from django.http import HttpResponse, Http404 from juser.models import User, UserGroup, DEPT from jasset.models import Asset, BisGroup from jlog.models import Log +from jasset.models import AssetAlias +from django.core.exceptions import ObjectDoesNotExist BASE_DIR = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) @@ -144,15 +147,6 @@ def pages(posts, r): return contact_list, p, contacts, page_range, current_page, show_first, show_end -def get_session_user_dept(request): - user_id = request.session.get('user_id', '') - user = User.objects.filter(id=user_id) - if user: - user = user[0] - dept = user.dept - return user, dept - - class PyCrypt(object): """This class used to encrypt and decrypt password.""" @@ -188,6 +182,14 @@ class ServerError(Exception): pass +def get_object(model, **kwargs): + try: + the_object = model.objects.get(**kwargs) + except ObjectDoesNotExist: + raise ServerError('Object get %s failed.' % str(kwargs.values())) + return the_object + + def require_login(func): """要求登录的装饰器""" def _deco(request, *args, **kwargs): @@ -235,6 +237,16 @@ def is_common_user(request): return False +@require_login +def get_session_user_dept(request): + user_id = request.session.get('user_id', 0) + user = User.objects.filter(id=user_id) + if user: + user = user[0] + dept = user.dept + return user, dept + + def get_user_dept(request): user_id = request.session.get('user_id') if user_id: @@ -310,6 +322,49 @@ def asset_perm_api(asset): return user_permed_list +def get_user_host(username): + """Get the hosts of under the user control.""" + hosts_attr = {} + asset_all = user_perm_asset_api(username) + user = User.objects.get(username=username) + for asset in asset_all: + alias = AssetAlias.objects.filter(user=user, host=asset) + if alias and alias[0].alias != '': + hosts_attr[asset.ip] = [asset.id, asset.ip, alias[0].alias] + else: + hosts_attr[asset.ip] = [asset.id, asset.ip, asset.comment] + return hosts_attr + + +def get_connect_item(username, ip): + asset = get_object(Asset, ip=ip) + port = asset.port + + if not asset.is_active: + raise ServerError('Host %s is not active.' % ip) + + user = get_object(User, username=username) + + if not user.is_active: + raise ServerError('User %s is not active.' % username) + + login_type_dict = { + 'L': user.ldap_pwd, + } + + if asset.login_type in login_type_dict: + password = CRYPTOR.decrypt(login_type_dict[asset.login_type]) + return username, password, ip, port + + elif asset.login_type == 'M': + username = asset.username + password = CRYPTOR.decrypt(asset.password) + return username, password, ip, port + + else: + raise ServerError('Login type is not in ["L", "M"]') + + def validate(request, user_group=None, user=None, asset_group=None, asset=None, edept=None): dept = get_session_user_dept(request)[1] if edept: @@ -362,3 +417,16 @@ def validate(request, user_group=None, user=None, asset_group=None, asset=None, def get_dept_asset(request): dept_id = get_user_dept(request) dept_asset = DEPT.objects.get(id=dept_id).asset_set.all() + + +def bash(cmd): + """执行bash命令""" + return subprocess.call(cmd, shell=True) + + +def is_dir(dir_name, username='root', mode=0755): + if not os.path.isdir(dir_name): + os.makedirs(dir_name) + bash("chown %s:%s '%s'" % (username, username, dir_name)) + os.chmod(dir_name, mode) + diff --git a/jumpserver/views.py b/jumpserver/views.py index d72f8f9be..7af477dc2 100644 --- a/jumpserver/views.py +++ b/jumpserver/views.py @@ -1,15 +1,13 @@ # coding: utf-8 from __future__ import division - -import datetime - from django.db.models import Count from django.shortcuts import render_to_response from django.template import RequestContext -from jasset.models import IDC -from juser.models import DEPT +from django.http import HttpResponseNotFound from jperm.models import Apply +from multiprocessing import Pool +import paramiko from jumpserver.api import * @@ -289,5 +287,64 @@ def install(request): return HttpResponse('Ok') +def transfer(sftp, filenames): + # pool = Pool(processes=5) + for filename, file_path in filenames.items(): + print filename, file_path + sftp.put(file_path, '/tmp/%s' % filename) + # pool.apply_async(transfer, (sftp, file_path, '/tmp/%s' % filename)) + sftp.close() + # pool.close() + # pool.join() + + def upload(request): - pass + user, dept = get_session_user_dept(request) + if request.method == 'POST': + hosts = request.POST.get('hosts') + upload_files = request.FILES.getlist('file[]', None) + upload_dir = "/tmp/%s" % user.username + is_dir(upload_dir) + date_now = datetime.datetime.now().strftime("%Y%m%d%H%M%S") + hosts_list = hosts.split(',') + user_hosts = get_user_host(user.username).keys() + unperm_hosts = [] + filenames = {} + for ip in hosts_list: + if ip not in user_hosts: + unperm_hosts.append(ip) + + if not hosts: + return HttpResponseNotFound(u'地址不能为空') + + if unperm_hosts: + print hosts_list + return HttpResponseNotFound(u'%s 没有权限.' % ', '.join(unperm_hosts)) + + for upload_file in upload_files: + file_path = '%s/%s.%s' % (upload_dir, upload_file.name, date_now) + filenames[upload_file.name] = file_path + f = open(file_path, 'w') + for chunk in upload_file.chunks(): + f.write(chunk) + f.close() + + sftps = [] + for host in hosts_list: + username, password, host, port = get_connect_item(user.username, host) + try: + t = paramiko.Transport((host, port)) + t.connect(username=username, password=password) + sftp = paramiko.SFTPClient.from_transport(t) + sftps.append(sftp) + except paramiko.AuthenticationException: + return HttpResponseNotFound(u'%s 连接失败.' % host) + + # pool = Pool(processes=5) + for sftp in sftps: + transfer(sftp, filenames) + # pool.close() + # pool.join() + return HttpResponse('传送成功') + + return render_to_response('upload.html', locals(), context_instance=RequestContext(request)) diff --git a/juser/views.py b/juser/views.py index a4f39076a..abda8dc25 100644 --- a/juser/views.py +++ b/juser/views.py @@ -26,18 +26,6 @@ def gen_rand_pwd(num): return salt -def bash(cmd): - """执行bash命令""" - return subprocess.call(cmd, shell=True) - - -def is_dir(dir_name, username='root', mode=0755): - if not os.path.isdir(dir_name): - os.makedirs(dir_name) - bash("chown %s:%s '%s'" % (username, username, dir_name)) - os.chmod(dir_name, mode) - - class AddError(Exception): pass @@ -1001,6 +989,9 @@ def chg_info(request): return render_to_response('juser/chg_info.html', locals(), context_instance=RequestContext(request)) + + + @require_login def down_key(request): user_id = '' diff --git a/templates/upload.html b/templates/upload.html index 9fc8f9e22..c2a19ebcb 100644 --- a/templates/upload.html +++ b/templates/upload.html @@ -1,15 +1,14 @@ {% extends 'base.html' %} {% load mytags %} -{% load humanize %} {% block content %} {% include 'nav_cat_bar.html' %} -
+
@@ -44,36 +48,53 @@