Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
J
jumpserver
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ops
jumpserver
Commits
78f00e5c
Commit
78f00e5c
authored
Apr 09, 2015
by
guanghongwei
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ϴļ
parent
30fd1600
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
174 additions
and
93 deletions
+174
-93
connect.py
connect.py
+3
-59
api.py
jumpserver/api.py
+77
-9
views.py
jumpserver/views.py
+63
-6
views.py
juser/views.py
+3
-12
upload.html
templates/upload.html
+28
-7
No files found.
connect.py
View file @
78f00e5c
...
@@ -17,15 +17,15 @@ import getpass
...
@@ -17,15 +17,15 @@ import getpass
import
fnmatch
import
fnmatch
import
readline
import
readline
from
multiprocessing
import
Pool
from
multiprocessing
import
Pool
from
ConfigParser
import
ConfigParser
from
django.core.exceptions
import
ObjectDoesNotExist
os
.
environ
[
'DJANGO_SETTINGS_MODULE'
]
=
'jumpserver.settings'
os
.
environ
[
'DJANGO_SETTINGS_MODULE'
]
=
'jumpserver.settings'
django
.
setup
()
django
.
setup
()
from
juser.models
import
User
from
juser.models
import
User
from
jasset.models
import
AssetAlias
from
jlog.models
import
Log
from
jlog.models
import
Log
from
jumpserver.api
import
*
from
jumpserver.api
import
*
try
:
try
:
import
termios
import
termios
import
tty
import
tty
...
@@ -57,10 +57,6 @@ def color_print_exit(msg, color='red'):
...
@@ -57,10 +57,6 @@ def color_print_exit(msg, color='red'):
sys
.
exit
()
sys
.
exit
()
class
ServerError
(
Exception
):
pass
def
get_win_size
():
def
get_win_size
():
"""This function use to get the size of the windows!"""
"""This function use to get the size of the windows!"""
if
'TIOCGWINSZ'
in
dir
(
termios
):
if
'TIOCGWINSZ'
in
dir
(
termios
):
...
@@ -81,14 +77,6 @@ def set_win_size(sig, data):
...
@@ -81,14 +77,6 @@ def set_win_size(sig, data):
pass
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
):
def
log_record
(
username
,
host
):
"""Logging user command and output."""
"""Logging user command and output."""
connect_log_dir
=
os
.
path
.
join
(
LOG_DIR
,
'connect'
)
connect_log_dir
=
os
.
path
.
join
(
LOG_DIR
,
'connect'
)
...
@@ -171,20 +159,6 @@ def posix_shell(chan, username, host):
...
@@ -171,20 +159,6 @@ def posix_shell(chan, username, host):
print_prompt
()
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
):
def
get_user_hostgroup
(
username
):
"""Get the hostgroups of under the user control."""
"""Get the hostgroups of under the user control."""
groups_attr
=
{}
groups_attr
=
{}
...
@@ -208,36 +182,6 @@ def get_user_hostgroup_host(username, gid):
...
@@ -208,36 +182,6 @@ def get_user_hostgroup_host(username, gid):
return
hosts_attr
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
):
def
verify_connect
(
username
,
part_ip
):
ip_matched
=
[]
ip_matched
=
[]
hosts_attr
=
get_user_host
(
username
)
hosts_attr
=
get_user_host
(
username
)
...
...
jumpserver/api.py
View file @
78f00e5c
...
@@ -11,11 +11,14 @@ import ldap
...
@@ -11,11 +11,14 @@ import ldap
from
ldap
import
modlist
from
ldap
import
modlist
import
hashlib
import
hashlib
import
datetime
import
datetime
import
subprocess
from
django.core.paginator
import
Paginator
,
EmptyPage
,
InvalidPage
from
django.core.paginator
import
Paginator
,
EmptyPage
,
InvalidPage
from
django.http
import
HttpResponse
,
Http404
from
django.http
import
HttpResponse
,
Http404
from
juser.models
import
User
,
UserGroup
,
DEPT
from
juser.models
import
User
,
UserGroup
,
DEPT
from
jasset.models
import
Asset
,
BisGroup
from
jasset.models
import
Asset
,
BisGroup
from
jlog.models
import
Log
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__
)))
BASE_DIR
=
os
.
path
.
abspath
(
os
.
path
.
dirname
(
os
.
path
.
dirname
(
__file__
)))
...
@@ -144,15 +147,6 @@ def pages(posts, r):
...
@@ -144,15 +147,6 @@ def pages(posts, r):
return
contact_list
,
p
,
contacts
,
page_range
,
current_page
,
show_first
,
show_end
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
):
class
PyCrypt
(
object
):
"""This class used to encrypt and decrypt password."""
"""This class used to encrypt and decrypt password."""
...
@@ -188,6 +182,14 @@ class ServerError(Exception):
...
@@ -188,6 +182,14 @@ class ServerError(Exception):
pass
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
require_login
(
func
):
"""要求登录的装饰器"""
"""要求登录的装饰器"""
def
_deco
(
request
,
*
args
,
**
kwargs
):
def
_deco
(
request
,
*
args
,
**
kwargs
):
...
@@ -235,6 +237,16 @@ def is_common_user(request):
...
@@ -235,6 +237,16 @@ def is_common_user(request):
return
False
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
):
def
get_user_dept
(
request
):
user_id
=
request
.
session
.
get
(
'user_id'
)
user_id
=
request
.
session
.
get
(
'user_id'
)
if
user_id
:
if
user_id
:
...
@@ -310,6 +322,49 @@ def asset_perm_api(asset):
...
@@ -310,6 +322,49 @@ def asset_perm_api(asset):
return
user_permed_list
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
):
def
validate
(
request
,
user_group
=
None
,
user
=
None
,
asset_group
=
None
,
asset
=
None
,
edept
=
None
):
dept
=
get_session_user_dept
(
request
)[
1
]
dept
=
get_session_user_dept
(
request
)[
1
]
if
edept
:
if
edept
:
...
@@ -362,3 +417,16 @@ def validate(request, user_group=None, user=None, asset_group=None, asset=None,
...
@@ -362,3 +417,16 @@ def validate(request, user_group=None, user=None, asset_group=None, asset=None,
def
get_dept_asset
(
request
):
def
get_dept_asset
(
request
):
dept_id
=
get_user_dept
(
request
)
dept_id
=
get_user_dept
(
request
)
dept_asset
=
DEPT
.
objects
.
get
(
id
=
dept_id
)
.
asset_set
.
all
()
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
)
jumpserver/views.py
View file @
78f00e5c
# coding: utf-8
# coding: utf-8
from
__future__
import
division
from
__future__
import
division
import
datetime
from
django.db.models
import
Count
from
django.db.models
import
Count
from
django.shortcuts
import
render_to_response
from
django.shortcuts
import
render_to_response
from
django.template
import
RequestContext
from
django.template
import
RequestContext
from
jasset.models
import
IDC
from
django.http
import
HttpResponseNotFound
from
juser.models
import
DEPT
from
jperm.models
import
Apply
from
jperm.models
import
Apply
from
multiprocessing
import
Pool
import
paramiko
from
jumpserver.api
import
*
from
jumpserver.api
import
*
...
@@ -289,5 +287,64 @@ def install(request):
...
@@ -289,5 +287,64 @@ def install(request):
return
HttpResponse
(
'Ok'
)
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
):
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
))
juser/views.py
View file @
78f00e5c
...
@@ -26,18 +26,6 @@ def gen_rand_pwd(num):
...
@@ -26,18 +26,6 @@ def gen_rand_pwd(num):
return
salt
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
):
class
AddError
(
Exception
):
pass
pass
...
@@ -1001,6 +989,9 @@ def chg_info(request):
...
@@ -1001,6 +989,9 @@ def chg_info(request):
return
render_to_response
(
'juser/chg_info.html'
,
locals
(),
context_instance
=
RequestContext
(
request
))
return
render_to_response
(
'juser/chg_info.html'
,
locals
(),
context_instance
=
RequestContext
(
request
))
@require_login
@require_login
def
down_key
(
request
):
def
down_key
(
request
):
user_id
=
''
user_id
=
''
...
...
templates/upload.html
View file @
78f00e5c
{% extends 'base.html' %}
{% extends 'base.html' %}
{% load mytags %}
{% load mytags %}
{% load humanize %}
{% block content %}
{% block content %}
{% include 'nav_cat_bar.html' %}
{% include 'nav_cat_bar.html' %}
<div
class=
"wrapper wrapper-content"
>
<div
class=
"wrapper wrapper-content
animated fadeIn
"
>
<div
class=
"row"
>
<div
class=
"row"
>
<div
class=
"col-lg-12"
>
<div
class=
"col-lg-12"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<div
class=
"ibox-title"
>
<h5>
Dropzone Area
</h5>
<h5>
上传文件
</h5>
<div
class=
"ibox-tools"
>
<div
class=
"ibox-tools"
>
<a
class=
"collapse-link"
>
<a
class=
"collapse-link"
>
<i
class=
"fa fa-chevron-up"
></i>
<i
class=
"fa fa-chevron-up"
></i>
...
@@ -29,12 +28,17 @@
...
@@ -29,12 +28,17 @@
</div>
</div>
</div>
</div>
<div
class=
"ibox-content"
>
<div
class=
"ibox-content"
>
<div
class=
""
>
<form
id=
"my-awesome-dropzone"
class=
"dropzone"
action=
"#"
>
<form
id=
"my-awesome-dropzone"
class=
"dropzone"
action=
"#"
>
<div
class=
"dropzone-previews"
></div>
<div
class=
"dropzone-previews"
>
<button
type=
"submit"
class=
"btn btn-primary pull-right"
>
Submit this form!
</button>
<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>
</form>
</div>
<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>
</div>
</div>
</div>
...
@@ -57,6 +61,7 @@
...
@@ -57,6 +61,7 @@
// Dropzone settings
// Dropzone settings
init
:
function
()
{
init
:
function
()
{
var
myDropzone
=
this
;
var
myDropzone
=
this
;
this
.
element
.
querySelector
(
"button[type=submit]"
).
addEventListener
(
"click"
,
function
(
e
)
{
this
.
element
.
querySelector
(
"button[type=submit]"
).
addEventListener
(
"click"
,
function
(
e
)
{
e
.
preventDefault
();
e
.
preventDefault
();
e
.
stopPropagation
();
e
.
stopPropagation
();
...
@@ -65,7 +70,7 @@
...
@@ -65,7 +70,7 @@
this
.
on
(
"sendingmultiple"
,
function
()
{
this
.
on
(
"sendingmultiple"
,
function
()
{
});
});
this
.
on
(
"successmultiple"
,
function
(
files
,
response
)
{
this
.
on
(
"successmultiple"
,
function
(
files
,
response
)
{
alert
(
files
)
alert
(
response
)
});
});
this
.
on
(
"errormultiple"
,
function
(
files
,
response
)
{
this
.
on
(
"errormultiple"
,
function
(
files
,
response
)
{
});
});
...
@@ -74,6 +79,22 @@
...
@@ -74,6 +79,22 @@
}
}
});
});
$
(
'#my-awesome-dropzone'
).
validator
({
timely
:
2
,
theme
:
"yellow_right_effect"
,
fields
:
{
"hosts"
:
{
rule
:
"required"
,
tip
:
"输入上传的Host"
,
ok
:
""
,
msg
:
{
required
:
"必须填写!"
}
}
},
valid
:
function
(
form
)
{
form
.
submit
();
}
});
</script>
</script>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment