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
2eda58ea
Commit
2eda58ea
authored
Jul 03, 2018
by
BaiJiangJie
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dev' of github.com:jumpserver/jumpserver into github_dev
parents
e1be8679
01afcf70
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
71 additions
and
44 deletions
+71
-44
api.py
apps/terminal/api.py
+64
-33
api.py
apps/users/api.py
+4
-8
user_detail.html
apps/users/templates/users/user_detail.html
+2
-2
requirements.txt
requirements/requirements.txt
+1
-1
No files found.
apps/terminal/api.py
View file @
2eda58ea
...
...
@@ -258,10 +258,35 @@ class SessionReplayViewSet(viewsets.ViewSet):
serializer_class
=
ReplaySerializer
permission_classes
=
(
IsSuperUserOrAppUser
,)
session
=
None
def
gen_session_path
(
self
):
upload_to
=
'replay'
# 仅添加到本地存储中
def
get_session_path
(
self
,
version
=
2
):
"""
获取session日志的文件路径
:param version: 原来后缀是 .gz,为了统一新版本改为 .replay.gz
:return:
"""
suffix
=
'.replay.gz'
if
version
==
1
:
suffix
=
'.gz'
date
=
self
.
session
.
date_start
.
strftime
(
'
%
Y-
%
m-
%
d'
)
return
os
.
path
.
join
(
date
,
str
(
self
.
session
.
id
)
+
'.gz'
)
return
os
.
path
.
join
(
date
,
str
(
self
.
session
.
id
)
+
suffix
)
def
get_local_path
(
self
,
version
=
2
):
session_path
=
self
.
get_session_path
(
version
=
version
)
if
version
==
2
:
local_path
=
os
.
path
.
join
(
self
.
upload_to
,
session_path
)
else
:
local_path
=
session_path
return
local_path
def
save_to_storage
(
self
,
f
):
local_path
=
self
.
get_local_path
()
try
:
name
=
default_storage
.
save
(
local_path
,
f
)
return
name
,
None
except
OSError
as
e
:
return
None
,
e
def
create
(
self
,
request
,
*
args
,
**
kwargs
):
session_id
=
kwargs
.
get
(
'pk'
)
...
...
@@ -270,42 +295,48 @@ class SessionReplayViewSet(viewsets.ViewSet):
if
serializer
.
is_valid
():
file
=
serializer
.
validated_data
[
'file'
]
file_path
=
self
.
gen_session_path
(
)
try
:
default_storage
.
save
(
file_path
,
file
)
return
Response
({
'url'
:
default_storage
.
url
(
file_path
)},
status
=
201
)
except
IOError
:
return
Response
(
"Save error"
,
status
=
500
)
name
,
err
=
self
.
save_to_storage
(
file
)
if
not
name
:
msg
=
"Failed save replay `{}`: {}"
.
format
(
session_id
,
err
)
logger
.
error
(
msg
)
return
Response
({
'msg'
:
str
(
err
)},
status
=
400
)
url
=
default_storage
.
url
(
name
)
return
Response
({
'url'
:
url
},
status
=
201
)
else
:
logger
.
error
(
'Update load data invalid: {}'
.
format
(
serializer
.
errors
)
)
msg
=
'Upload data invalid: {}'
.
format
(
serializer
.
errors
)
logger
.
error
(
msg
)
return
Response
({
'msg'
:
serializer
.
errors
},
status
=
401
)
def
retrieve
(
self
,
request
,
*
args
,
**
kwargs
):
session_id
=
kwargs
.
get
(
'pk'
)
self
.
session
=
get_object_or_404
(
Session
,
id
=
session_id
)
path
=
self
.
gen_session_path
()
if
default_storage
.
exists
(
path
):
url
=
default_storage
.
url
(
path
)
return
redirect
(
url
)
else
:
configs
=
settings
.
TERMINAL_REPLAY_STORAGE
configs
=
[
cfg
for
cfg
in
configs
if
cfg
[
'TYPE'
]
!=
'server'
]
if
not
configs
:
return
HttpResponseNotFound
()
date
=
self
.
session
.
date_start
.
strftime
(
'
%
Y-
%
m-
%
d'
)
file_path
=
os
.
path
.
join
(
date
,
str
(
self
.
session
.
id
)
+
'.replay.gz'
)
target_path
=
default_storage
.
base_location
+
'/'
+
path
storage
=
jms_storage
.
get_multi_object_storage
(
configs
)
ok
,
err
=
storage
.
download
(
file_path
,
target_path
)
if
ok
:
return
redirect
(
default_storage
.
url
(
path
))
else
:
logger
.
error
(
"Failed download replay file: {}"
.
format
(
err
))
return
HttpResponseNotFound
()
# 新版本和老版本的文件后缀不同
session_path
=
self
.
get_session_path
()
# 存在外部存储上的路径
local_path
=
self
.
get_local_path
()
local_path_v1
=
self
.
get_local_path
(
version
=
1
)
# 去default storage中查找
for
_local_path
in
(
local_path
,
local_path_v1
,
session_path
):
if
default_storage
.
exists
(
_local_path
):
url
=
default_storage
.
url
(
_local_path
)
return
redirect
(
url
)
# 去定义的外部storage查找
configs
=
settings
.
TERMINAL_REPLAY_STORAGE
configs
=
{
k
:
v
for
k
,
v
in
configs
.
items
()
if
v
[
'TYPE'
]
!=
'server'
}
if
not
configs
:
return
HttpResponseNotFound
()
target_path
=
os
.
path
.
join
(
default_storage
.
base_location
,
local_path
)
# 保存到storage的路径
target_dir
=
os
.
path
.
dirname
(
target_path
)
if
not
os
.
path
.
isdir
(
target_dir
):
os
.
makedirs
(
target_dir
,
exist_ok
=
True
)
storage
=
jms_storage
.
get_multi_object_storage
(
configs
)
ok
,
err
=
storage
.
download
(
session_path
,
target_path
)
if
not
ok
:
logger
.
error
(
"Failed download replay file: {}"
.
format
(
err
))
return
HttpResponseNotFound
()
return
redirect
(
default_storage
.
url
(
local_path
))
class
SessionReplayV2ViewSet
(
SessionReplayViewSet
):
...
...
apps/users/api.py
View file @
2eda58ea
...
...
@@ -128,16 +128,12 @@ class UserToken(APIView):
return
Response
({
'error'
:
msg
},
status
=
406
)
class
UserProfile
(
APIView
):
permission_classes
=
(
Is
ValidUser
,)
class
UserProfile
(
generics
.
Retrieve
APIView
):
permission_classes
=
(
Is
Authenticated
,)
serializer_class
=
UserSerializer
def
get
(
self
,
request
):
# return Response(request.user.to_json())
return
Response
(
self
.
serializer_class
(
request
.
user
)
.
data
)
def
post
(
self
,
request
):
return
Response
(
self
.
serializer_class
(
request
.
user
)
.
data
)
def
get_object
(
self
):
return
self
.
request
.
user
class
UserOtpAuthApi
(
APIView
):
...
...
apps/users/templates/users/user_detail.html
View file @
2eda58ea
...
...
@@ -421,8 +421,8 @@ $(document).ready(function() {
APIUpdateAttr({ url: the_url, body: JSON.stringify(body), success: success, error: fail});
}).on('click', '.btn-delete-user', function () {
var $this = $(this);
var name = "{{ user.name }}";
var uid = "{{ user.id }}";
var name = "{{ user
_object
.name }}";
var uid = "{{ user
_object
.id }}";
var the_url = '{% url "api-users:user-detail" pk=DEFAULT_PK %}'.replace('{{ DEFAULT_PK }}', uid);
var redirect_url = "{% url 'users:user-list' %}";
objectDelete($this, name, the_url, redirect_url);
...
...
requirements/requirements.txt
View file @
2eda58ea
...
...
@@ -61,7 +61,7 @@ pytz==2018.3
PyYAML==3.12
redis==2.10.6
requests==2.18.4
jms-storage==0.0.1
7
jms-storage==0.0.1
8
s3transfer==0.1.13
simplejson==3.13.2
six==1.11.0
...
...
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