mirror of https://github.com/jumpserver/jumpserver
上传文件
parent
30fd160079
commit
78f00e5c5f
62
connect.py
62
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)
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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 = ''
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load mytags %}
|
||||
{% load humanize %}
|
||||
{% block content %}
|
||||
{% include 'nav_cat_bar.html' %}
|
||||
|
||||
<div class="wrapper wrapper-content">
|
||||
<div class="wrapper wrapper-content animated fadeIn">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="ibox-title">
|
||||
<h5>Dropzone Area</h5>
|
||||
<h5>涓婁紶鏂囦欢</h5>
|
||||
<div class="ibox-tools">
|
||||
<a class="collapse-link">
|
||||
<i class="fa fa-chevron-up"></i>
|
||||
|
@ -29,12 +28,17 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="ibox-content">
|
||||
<form id="my-awesome-dropzone" class="dropzone" action="#">
|
||||
<div class="dropzone-previews"></div>
|
||||
<button type="submit" class="btn btn-primary pull-right">Submit this form!</button>
|
||||
</form>
|
||||
<div class="">
|
||||
<form id="my-awesome-dropzone" class="dropzone" action="#">
|
||||
<div class="dropzone-previews">
|
||||
<input id="hosts" name="hosts" type="text" class="form-control" required="涓嶈兘涓虹┖" placeholder="杈撳叆涓绘満鍦板潃锛岄楀彿闅斿紑锛岀‘淇濅綘鏈夎緭鍏ヤ富鏈哄湴鍧鐨勬潈闄" size="80%">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary pull-right">鍏ㄩ儴涓婁紶</button>
|
||||
<div></div>
|
||||
</form>
|
||||
</div>
|
||||
<div>
|
||||
<div class="m text-right"><small>DropzoneJS is an open source library that provides drag'n'drop file uploads with image previews: <a href="https://github.com/enyo/dropzone" target="_blank">https://github.com/enyo/dropzone</a></small> </div>
|
||||
<div class="m text-right"><small>涓婁紶鏂囦欢鍒板悗绔湇鍔″櫒鐨/tmp涓锛璇锋敞鎰忔煡鐪</small> </div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -44,36 +48,53 @@
|
|||
|
||||
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
$(document).ready(function(){
|
||||
|
||||
Dropzone.options.myAwesomeDropzone = {
|
||||
Dropzone.options.myAwesomeDropzone = {
|
||||
|
||||
autoProcessQueue: false,
|
||||
uploadMultiple: true,
|
||||
parallelUploads: 100,
|
||||
maxFiles: 100,
|
||||
url: '/upload/',
|
||||
autoProcessQueue: false,
|
||||
uploadMultiple: true,
|
||||
parallelUploads: 100,
|
||||
maxFiles: 100,
|
||||
url: '/upload/',
|
||||
|
||||
// Dropzone settings
|
||||
init: function() {
|
||||
var myDropzone = this;
|
||||
this.element.querySelector("button[type=submit]").addEventListener("click", function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
myDropzone.processQueue();
|
||||
});
|
||||
this.on("sendingmultiple", function() {
|
||||
});
|
||||
this.on("successmultiple", function(files, response) {
|
||||
alert(files)
|
||||
});
|
||||
this.on("errormultiple", function(files, response) {
|
||||
});
|
||||
}
|
||||
// Dropzone settings
|
||||
init: function() {
|
||||
var myDropzone = this;
|
||||
|
||||
this.element.querySelector("button[type=submit]").addEventListener("click", function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
myDropzone.processQueue();
|
||||
});
|
||||
this.on("sendingmultiple", function() {
|
||||
});
|
||||
this.on("successmultiple", function(files, response) {
|
||||
alert(response)
|
||||
});
|
||||
this.on("errormultiple", function(files, response) {
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
$('#my-awesome-dropzone').validator({
|
||||
timely: 2,
|
||||
theme: "yellow_right_effect",
|
||||
fields: {
|
||||
"hosts": {
|
||||
rule: "required",
|
||||
tip: "杈撳叆涓婁紶鐨凥ost",
|
||||
ok: "",
|
||||
msg: {required: "蹇呴』濉啓!"}
|
||||
}
|
||||
},
|
||||
valid: function(form) {
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
|
|
Loading鈥
Reference in New Issue