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
de2416b1
Commit
de2416b1
authored
May 24, 2018
by
BaiJiangJie
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dev' of github.com:jumpserver/jumpserver into github_dev
parents
486793dd
c529061e
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
216 additions
and
111 deletions
+216
-111
system_user.py
apps/assets/api/system_user.py
+6
-1
base.py
apps/assets/models/base.py
+1
-0
node.py
apps/assets/models/node.py
+6
-2
system_user_detail.html
apps/assets/templates/assets/system_user_detail.html
+21
-4
django.mo
apps/i18n/zh/LC_MESSAGES/django.mo
+0
-0
django.po
apps/i18n/zh/LC_MESSAGES/django.po
+38
-23
api.py
apps/perms/api.py
+7
-2
utils.py
apps/perms/utils.py
+30
-4
api.py
apps/terminal/api.py
+14
-32
__init__.py
apps/terminal/backends/__init__.py
+8
-8
es.py
apps/terminal/backends/command/es.py
+5
-24
serializers.py
apps/terminal/serializers.py
+2
-2
terminal_tags.py
apps/terminal/templatetags/terminal_tags.py
+2
-2
command.py
apps/terminal/views/command.py
+2
-2
session.py
apps/terminal/views/session.py
+2
-2
group.py
apps/users/models/group.py
+1
-1
requirements.txt
requirements/requirements.txt
+1
-2
clean_duplicate_user_groups.py
utils/clean_duplicate_user_groups.py
+70
-0
No files found.
apps/assets/api/system_user.py
View file @
de2416b1
...
...
@@ -40,7 +40,7 @@ class SystemUserViewSet(BulkModelViewSet):
permission_classes
=
(
IsSuperUserOrAppUser
,)
class
SystemUserAuthInfoApi
(
generics
.
RetrieveUpdateAPIView
):
class
SystemUserAuthInfoApi
(
generics
.
RetrieveUpdate
Destroy
APIView
):
"""
Get system user auth info
"""
...
...
@@ -48,6 +48,11 @@ class SystemUserAuthInfoApi(generics.RetrieveUpdateAPIView):
permission_classes
=
(
IsSuperUserOrAppUser
,)
serializer_class
=
serializers
.
SystemUserAuthSerializer
def
destroy
(
self
,
request
,
*
args
,
**
kwargs
):
instance
=
self
.
get_object
()
instance
.
clear_auth
()
return
Response
(
status
=
204
)
class
SystemUserPushApi
(
generics
.
RetrieveAPIView
):
"""
...
...
apps/assets/models/base.py
View file @
de2416b1
...
...
@@ -107,6 +107,7 @@ class AssetUser(models.Model):
def
clear_auth
(
self
):
self
.
_password
=
''
self
.
_private_key
=
''
self
.
_public_key
=
''
self
.
save
()
def
auto_gen_auth
(
self
):
...
...
apps/assets/models/node.py
View file @
de2416b1
...
...
@@ -61,10 +61,14 @@ class Node(models.Model):
return
child
def
get_children
(
self
):
return
self
.
__class__
.
objects
.
filter
(
key__regex
=
r'^{}:[0-9]+$'
.
format
(
self
.
key
))
return
self
.
__class__
.
objects
.
filter
(
key__regex
=
r'^{}:[0-9]+$'
.
format
(
self
.
key
)
)
def
get_all_children
(
self
):
return
self
.
__class__
.
objects
.
filter
(
key__startswith
=
'{}:'
.
format
(
self
.
key
))
return
self
.
__class__
.
objects
.
filter
(
key__startswith
=
'{}:'
.
format
(
self
.
key
)
)
def
get_family
(
self
):
children
=
list
(
self
.
get_all_children
())
...
...
apps/assets/templates/assets/system_user_detail.html
View file @
de2416b1
...
...
@@ -107,14 +107,14 @@
</div>
<div
class=
"col-sm-4"
style=
"padding-left: 0;padding-right: 0"
>
<div
class=
"panel panel-primary
only-ssh
"
>
<div
class=
"panel panel-primary "
>
<div
class=
"panel-heading"
>
<i
class=
"fa fa-info-circle"
></i>
{% trans 'Quick update' %}
</div>
<div
class=
"panel-body"
>
<table
class=
"table"
>
<tbody>
<tr
class=
"
no-borders-tr
"
>
<tr
class=
"
only-ssh
"
>
<td
width=
"50%"
>
{% trans 'Auto push' %}:
</td>
<td>
<span
class=
"pull-right"
>
...
...
@@ -130,8 +130,8 @@
</span>
</td>
</tr>
<tr
class=
"no-borders-tr"
>
{% if system_user.auto_push %}
<tr
class=
"only-ssh"
>
<td
width=
"50%"
>
{% trans 'Push system user now' %}:
</td>
<td>
<span
style=
"float: right"
>
...
...
@@ -139,8 +139,8 @@
</span>
</td>
</tr>
<tr>
{% endif %}
<tr
class=
"only-ssh"
>
<td
width=
"50%"
>
{% trans 'Test assets connective' %}:
</td>
<td>
<span
style=
"float: right"
>
...
...
@@ -149,6 +149,15 @@
</td>
</tr>
<tr>
<td
width=
"50%"
>
{% trans 'Clear auth' %}:
</td>
<td>
<span
style=
"float: right"
>
<button
type=
"button"
class=
"btn btn-primary btn-xs btn-clear-auth"
style=
"width: 54px"
>
{% trans 'Clear' %}
</button>
</span>
</td>
</tr>
{#
<tr>
#}
{#
<td
width=
"50%"
>
{% trans 'Change auth period' %}:
</td>
#}
{#
<td>
#}
...
...
@@ -239,6 +248,7 @@ $(document).ready(function () {
if
(
$
(
'#id_protocol_type'
).
text
()
===
'rdp'
){
$
(
'.only-ssh'
).
addClass
(
'hidden'
)
}
$
(
".panel-body .table tr:visible:first"
).
addClass
(
'no-borders-tr'
);
$
(
'.select2'
).
select2
()
.
on
(
'select2:select'
,
function
(
evt
)
{
var
data
=
evt
.
params
.
data
;
...
...
@@ -321,6 +331,13 @@ $(document).ready(function () {
success
:
success
,
flash_message
:
false
});
}).
on
(
'click'
,
'.btn-clear-auth'
,
function
()
{
var
the_url
=
'{% url "api-assets:system-user-auth-info" pk=system_user.id %}'
;
APIUpdateAttr
({
url
:
the_url
,
method
:
'DELETE'
,
success_message
:
"{% trans 'Clear auth' %}"
+
" {% trans 'success' %}"
});
})
</script>
{% endblock %}
apps/i18n/zh/LC_MESSAGES/django.mo
View file @
de2416b1
No preview for this file type
apps/i18n/zh/LC_MESSAGES/django.po
View file @
de2416b1
...
...
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Jumpserver 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-05-
08 17:24
+0800\n"
"POT-Creation-Date: 2018-05-
17 11:32
+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: ibuler <ibuler@qq.com>\n"
"Language-Team: Jumpserver team<ibuler@qq.com>\n"
...
...
@@ -17,22 +17,22 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: assets/api/node.py:
9
6
#: assets/api/node.py:
10
6
msgid "New node {}"
msgstr "新节点 {}"
#: assets/api/node.py:2
25
#: assets/api/node.py:2
42
msgid "更新节点资产硬件信息: {}"
msgstr ""
#: assets/api/node.py:2
38
#: assets/api/node.py:2
55
msgid "测试节点下资产是否可连接: {}"
msgstr ""
#: assets/forms/asset.py:24 assets/models/asset.py:66 assets/models/user.py:103
#: assets/templates/assets/asset_detail.html:183
#: assets/templates/assets/asset_detail.html:191
#: assets/templates/assets/system_user_detail.html:1
66
perms/models.py:33
#: assets/templates/assets/system_user_detail.html:1
75
perms/models.py:33
msgid "Nodes"
msgstr "节点管理"
...
...
@@ -438,7 +438,7 @@ msgstr "默认资产组"
msgid "User"
msgstr "用户"
#: assets/models/label.py:18 assets/models/node.py:1
5
#: assets/models/label.py:18 assets/models/node.py:1
8
#: assets/templates/assets/label_list.html:15 common/models.py:27
msgid "Value"
msgstr "值"
...
...
@@ -535,7 +535,7 @@ msgstr "测试系统用户可连接性: {}"
msgid "定期测试系统用户可连接性: {}"
msgstr ""
#: assets/tasks.py:40
1
#: assets/tasks.py:40
2
msgid "推送系统用户到入资产: {}"
msgstr ""
...
...
@@ -660,7 +660,7 @@ msgstr "重置"
#: common/templates/common/ldap_setting.html:60
#: common/templates/common/terminal_setting.html:103
#: perms/templates/perms/asset_permission_create_update.html:70
#: terminal/templates/terminal/session_list.html:12
0
#: terminal/templates/terminal/session_list.html:12
4
#: terminal/templates/terminal/terminal_update.html:48
#: users/templates/users/_user.html:47
#: users/templates/users/forgot_password.html:44
...
...
@@ -782,8 +782,8 @@ msgstr "选择节点"
#: assets/templates/assets/admin_user_detail.html:100
#: assets/templates/assets/asset_detail.html:200
#: assets/templates/assets/asset_list.html:63
4
#: assets/templates/assets/system_user_detail.html:1
83
#: assets/templates/assets/asset_list.html:63
6
#: assets/templates/assets/system_user_detail.html:1
92
#: assets/templates/assets/system_user_list.html:138 templates/_modal.html:22
#: terminal/templates/terminal/session_detail.html:108
#: users/templates/users/user_detail.html:362
...
...
@@ -963,19 +963,19 @@ msgstr "仅显示当前节点资产"
msgid "Displays all child node assets"
msgstr "显示所有子节点资产"
#: assets/templates/assets/asset_list.html:21
5
#: assets/templates/assets/asset_list.html:21
7
msgid "Create node failed"
msgstr "创建节点失败"
#: assets/templates/assets/asset_list.html:22
7
#: assets/templates/assets/asset_list.html:22
9
msgid "Have child node, cancel"
msgstr "存在子节点,不能删除"
#: assets/templates/assets/asset_list.html:2
29
#: assets/templates/assets/asset_list.html:2
31
msgid "Have assets, cancel"
msgstr "存在资产,不能删除"
#: assets/templates/assets/asset_list.html:6
29
#: assets/templates/assets/asset_list.html:6
31
#: assets/templates/assets/system_user_list.html:133
#: users/templates/users/user_detail.html:357
#: users/templates/users/user_detail.html:382
...
...
@@ -984,20 +984,20 @@ msgstr "存在资产,不能删除"
msgid "Are you sure?"
msgstr "你确认吗?"
#: assets/templates/assets/asset_list.html:63
0
#: assets/templates/assets/asset_list.html:63
2
msgid "This will delete the selected assets !!!"
msgstr "删除选择资产"
#: assets/templates/assets/asset_list.html:6
38
#: assets/templates/assets/asset_list.html:6
40
msgid "Asset Deleted."
msgstr "已被删除"
#: assets/templates/assets/asset_list.html:6
39
#: assets/templates/assets/asset_list.html:64
4
#: assets/templates/assets/asset_list.html:6
41
#: assets/templates/assets/asset_list.html:64
6
msgid "Asset Delete"
msgstr "删除"
#: assets/templates/assets/asset_list.html:64
3
#: assets/templates/assets/asset_list.html:64
5
msgid "Asset Deleting failed."
msgstr "删除失败"
...
...
@@ -1032,6 +1032,7 @@ msgid "Create gateway"
msgstr "创建网关"
#: assets/templates/assets/domain_gateway_list.html:87
#: assets/templates/assets/domain_gateway_list.html:89
#: common/templates/common/email_setting.html:58
#: common/templates/common/ldap_setting.html:58
msgid "Test connection"
...
...
@@ -1080,10 +1081,23 @@ msgstr "家目录"
msgid "Uid"
msgstr "Uid"
#: assets/templates/assets/system_user_detail.html:174
#: assets/templates/assets/system_user_detail.html:153
#: assets/templates/assets/system_user_detail.html:339
msgid "Clear auth"
msgstr "清除认证信息"
#: assets/templates/assets/system_user_detail.html:156
msgid "Clear"
msgstr "清除"
#: assets/templates/assets/system_user_detail.html:183
msgid "Add to node"
msgstr "添加到节点"
#: assets/templates/assets/system_user_detail.html:339
msgid "success"
msgstr "成功"
#: assets/templates/assets/system_user_list.html:18
#: assets/views/system_user.py:45
msgid "Create system user"
...
...
@@ -2113,15 +2127,16 @@ msgstr "时长"
msgid "Monitor"
msgstr "监控"
#: terminal/templates/terminal/session_list.html:105
#: terminal/templates/terminal/session_list.html:106
#: terminal/templates/terminal/session_list.html:108
msgid "Terminate"
msgstr "终断"
#: terminal/templates/terminal/session_list.html:1
16
#: terminal/templates/terminal/session_list.html:1
20
msgid "Terminate selected"
msgstr "终断所选"
#: terminal/templates/terminal/session_list.html:1
36
#: terminal/templates/terminal/session_list.html:1
40
msgid "Terminate task send, waiting ..."
msgstr "终断任务已发送,请等待"
...
...
apps/perms/api.py
View file @
de2416b1
...
...
@@ -6,7 +6,7 @@ from rest_framework.views import APIView, Response
from
rest_framework.generics
import
ListAPIView
,
get_object_or_404
,
RetrieveUpdateAPIView
from
rest_framework
import
viewsets
from
common.utils
import
set_or_append_attr_bulk
from
common.utils
import
set_or_append_attr_bulk
,
get_object_or_none
from
users.permissions
import
IsValidUser
,
IsSuperUser
,
IsSuperUserOrAppUser
from
.utils
import
AssetPermissionUtil
from
.models
import
AssetPermission
...
...
@@ -147,8 +147,13 @@ class UserGrantedNodeAssetsApi(ListAPIView):
user
=
get_object_or_404
(
User
,
id
=
user_id
)
else
:
user
=
self
.
request
.
user
node
=
get_object_or_404
(
Node
,
id
=
node_id
)
nodes
=
AssetPermissionUtil
.
get_user_nodes_with_assets
(
user
)
node
=
get_object_or_none
(
Node
,
id
=
node_id
)
if
not
node
:
unnode
=
[
node
for
node
in
nodes
if
node
.
name
==
'Unnode'
]
node
=
unnode
[
0
]
if
unnode
else
None
assets
=
nodes
.
get
(
node
,
[])
for
asset
,
system_users
in
assets
.
items
():
asset
.
system_users_granted
=
system_users
...
...
apps/perms/utils.py
View file @
de2416b1
...
...
@@ -13,7 +13,6 @@ logger = get_logger(__file__)
class
AssetPermissionUtil
:
@staticmethod
def
get_user_permissions
(
user
):
return
AssetPermission
.
objects
.
all
()
.
valid
()
.
filter
(
users
=
user
)
...
...
@@ -122,6 +121,24 @@ class AssetPermissionUtil:
nodes
[
node
]
.
update
(
set
(
_system_users
))
return
nodes
@classmethod
def
get_user_nodes_inherit_group
(
cls
,
user
):
nodes
=
defaultdict
(
set
)
groups
=
user
.
groups
.
all
()
for
group
in
groups
:
_nodes
=
cls
.
get_user_group_nodes
(
group
)
for
node
,
system_users
in
_nodes
.
items
():
nodes
[
node
]
.
update
(
set
(
system_users
))
return
nodes
@classmethod
def
get_user_nodes
(
cls
,
user
):
nodes
=
cls
.
get_user_nodes_direct
(
user
)
nodes_inherit
=
cls
.
get_user_nodes_inherit_group
(
user
)
for
node
,
system_users
in
nodes_inherit
.
items
():
nodes
[
node
]
.
update
(
set
(
system_users
))
return
nodes
@classmethod
def
get_user_nodes_assets_direct
(
cls
,
user
):
assets
=
defaultdict
(
set
)
...
...
@@ -164,15 +181,24 @@ class AssetPermissionUtil:
:param user:
:return: {node: {asset: set(su1, su2)}}
"""
from
assets.models
import
Node
unnode
=
Node
(
value
=
'Unnode'
)
nodes
=
defaultdict
(
dict
)
for
_node
in
cls
.
get_user_nodes
(
user
):
children
=
_node
.
get_family
()
for
node
in
children
:
nodes
[
node
]
=
defaultdict
(
set
)
nodes
[
unnode
]
=
defaultdict
(
set
)
_assets
=
cls
.
get_user_assets
(
user
)
for
asset
,
_system_users
in
_assets
.
items
():
_nodes
=
asset
.
get_nodes
()
in_node
=
False
for
node
in
_nodes
:
if
asset
in
nodes
[
node
]:
if
node
in
nodes
:
in_node
=
True
nodes
[
node
][
asset
]
.
update
(
_system_users
)
els
e
:
nodes
[
node
][
asset
]
=
_system_users
if
not
in_nod
e
:
nodes
[
unnode
][
asset
]
.
update
(
_system_users
)
return
nodes
@classmethod
...
...
apps/terminal/api.py
View file @
de2416b1
...
...
@@ -9,6 +9,7 @@ from django.core.cache import cache
from
django.shortcuts
import
get_object_or_404
,
redirect
from
django.utils
import
timezone
from
django.core.files.storage
import
default_storage
from
django.http.response
import
HttpResponseRedirectBase
from
django.http
import
HttpResponseNotFound
from
django.conf
import
settings
...
...
@@ -25,7 +26,7 @@ from .serializers import TerminalSerializer, StatusSerializer, \
SessionSerializer
,
TaskSerializer
,
ReplaySerializer
from
.hands
import
IsSuperUserOrAppUser
,
IsAppUser
,
\
IsSuperUserOrAppUserOrUserReadonly
from
.backends
import
get_command_stor
e
,
get_multi_command_stor
e
,
\
from
.backends
import
get_command_stor
age
,
get_multi_command_storag
e
,
\
SessionCommandSerializer
logger
=
logging
.
getLogger
(
__file__
)
...
...
@@ -227,8 +228,8 @@ class CommandViewSet(viewsets.ViewSet):
}
"""
command_store
=
get_command_store
()
multi_command_storage
=
get_multi_command_store
()
command_store
=
get_command_stor
ag
e
()
multi_command_storage
=
get_multi_command_stor
ag
e
()
serializer_class
=
SessionCommandSerializer
permission_classes
=
(
IsSuperUserOrAppUser
,)
...
...
@@ -291,19 +292,20 @@ class SessionReplayViewSet(viewsets.ViewSet):
url
=
default_storage
.
url
(
path
)
return
redirect
(
url
)
else
:
configs
=
settings
.
TERMINAL_REPLAY_STORAGE
.
items
()
configs
=
settings
.
TERMINAL_REPLAY_STORAGE
configs
=
[
cfg
for
cfg
in
configs
if
cfg
[
'TYPE'
]
!=
'server'
]
if
not
configs
:
return
HttpResponseNotFound
()
for
name
,
config
in
configs
:
client
=
jms_storage
.
init
(
config
)
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
if
client
and
client
.
has_file
(
file_path
)
and
\
client
.
download_file
(
file_path
,
target_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
()
...
...
@@ -313,33 +315,13 @@ class SessionReplayV2ViewSet(SessionReplayViewSet):
session
=
None
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
()
response
=
super
()
.
retrieve
(
request
,
*
args
,
**
kwargs
)
data
=
{
'type'
:
'guacamole'
if
self
.
session
.
protocol
==
'rdp'
else
'json'
,
'src'
:
''
,
}
if
default_storage
.
exists
(
path
):
url
=
default_storage
.
url
(
path
)
data
[
'src'
]
=
url
return
Response
(
data
)
else
:
configs
=
settings
.
TERMINAL_REPLAY_STORAGE
.
items
()
if
not
configs
:
return
HttpResponseNotFound
()
for
name
,
config
in
configs
:
client
=
jms_storage
.
init
(
config
)
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
if
client
and
client
.
has_file
(
file_path
)
and
\
client
.
download_file
(
file_path
,
target_path
):
url
=
default_storage
.
url
(
path
)
data
[
'src'
]
=
url
if
isinstance
(
response
,
HttpResponseRedirectBase
):
data
[
'src'
]
=
response
.
url
return
Response
(
data
)
return
HttpResponseNotFound
()
...
...
apps/terminal/backends/__init__.py
View file @
de2416b1
...
...
@@ -7,19 +7,19 @@ TYPE_ENGINE_MAPPING = {
}
def
get_command_store
():
params
=
settings
.
COMMAND_STORAGE
engine_class
=
import_module
(
params
[
'ENGINE'
])
storage
=
engine_class
.
CommandStore
(
params
)
def
get_command_stor
ag
e
():
config
=
settings
.
COMMAND_STORAGE
engine_class
=
import_module
(
config
[
'ENGINE'
])
storage
=
engine_class
.
CommandStore
(
config
)
return
storage
def
get_terminal_command_stor
e
():
def
get_terminal_command_stor
ages
():
storage_list
=
{}
for
name
,
params
in
settings
.
TERMINAL_COMMAND_STORAGE
.
items
():
tp
=
params
[
'TYPE'
]
if
tp
==
'server'
:
storage
=
get_command_store
()
storage
=
get_command_stor
ag
e
()
else
:
if
not
TYPE_ENGINE_MAPPING
.
get
(
tp
):
continue
...
...
@@ -29,9 +29,9 @@ def get_terminal_command_store():
return
storage_list
def
get_multi_command_store
():
def
get_multi_command_stor
ag
e
():
from
.command.multi
import
CommandStore
storage_list
=
get_terminal_command_stor
e
()
.
values
()
storage_list
=
get_terminal_command_stor
ages
()
.
values
()
storage
=
CommandStore
(
storage_list
)
return
storage
...
...
apps/terminal/backends/command/es.py
View file @
de2416b1
# -*- coding: utf-8 -*-
#
from
jms_
es_sdk
import
ESStor
e
from
jms_
storage.es
import
ESStorag
e
from
.base
import
CommandBase
from
.models
import
AbstractSessionCommand
class
CommandStore
(
CommandBase
,
ESStor
e
):
class
CommandStore
(
ESStorage
,
CommandBas
e
):
def
__init__
(
self
,
params
):
hosts
=
params
.
get
(
'HOSTS'
,
[
'http://localhost'
])
ESStore
.
__init__
(
self
,
hosts
=
hosts
)
def
save
(
self
,
command
):
return
ESStore
.
save
(
self
,
command
)
def
bulk_save
(
self
,
commands
):
return
ESStore
.
bulk_save
(
self
,
commands
)
super
()
.
__init__
(
params
)
def
filter
(
self
,
date_from
=
None
,
date_to
=
None
,
user
=
None
,
asset
=
None
,
system_user
=
None
,
input
=
None
,
session
=
None
):
data
=
ESStore
.
filter
(
self
,
date_from
=
date_from
,
date_to
=
date_to
,
data
=
super
()
.
filter
(
date_from
=
date_from
,
date_to
=
date_to
,
user
=
user
,
asset
=
asset
,
system_user
=
system_user
,
input
=
input
,
session
=
session
)
input
=
input
,
session
=
session
)
return
AbstractSessionCommand
.
from_multi_dict
(
[
item
[
"_source"
]
for
item
in
data
[
"hits"
]
if
item
]
)
def
count
(
self
,
date_from
=
None
,
date_to
=
None
,
user
=
None
,
asset
=
None
,
system_user
=
None
,
input
=
None
,
session
=
None
):
amount
=
ESStore
.
count
(
self
,
date_from
=
date_from
,
date_to
=
date_to
,
user
=
user
,
asset
=
asset
,
system_user
=
system_user
,
input
=
input
,
session
=
session
)
return
amount
apps/terminal/serializers.py
View file @
de2416b1
...
...
@@ -9,7 +9,7 @@ from rest_framework_bulk.serializers import BulkListSerializer
from
common.mixins
import
BulkSerializerMixin
from
common.utils
import
get_object_or_none
from
.models
import
Terminal
,
Status
,
Session
,
Task
from
.backends
import
get_multi_command_store
from
.backends
import
get_multi_command_stor
ag
e
class
TerminalSerializer
(
serializers
.
ModelSerializer
):
...
...
@@ -47,7 +47,7 @@ class TerminalSerializer(serializers.ModelSerializer):
class
SessionSerializer
(
serializers
.
ModelSerializer
):
command_amount
=
serializers
.
SerializerMethodField
()
command_store
=
get_multi_command_store
()
command_store
=
get_multi_command_stor
ag
e
()
class
Meta
:
model
=
Session
...
...
apps/terminal/templatetags/terminal_tags.py
View file @
de2416b1
# ~*~ coding: utf-8 ~*~
from
django
import
template
from
..backends
import
get_multi_command_store
from
..backends
import
get_multi_command_stor
ag
e
register
=
template
.
Library
()
command_store
=
get_multi_command_store
()
command_store
=
get_multi_command_stor
ag
e
()
@register.filter
...
...
apps/terminal/views/command.py
View file @
de2416b1
...
...
@@ -9,10 +9,10 @@ from django.utils.translation import ugettext as _
from
common.mixins
import
DatetimeSearchMixin
,
AdminUserRequiredMixin
from
..models
import
Command
from
..
import
utils
from
..backends
import
get_multi_command_store
from
..backends
import
get_multi_command_stor
ag
e
__all__
=
[
'CommandListView'
]
common_storage
=
get_multi_command_store
()
common_storage
=
get_multi_command_stor
ag
e
()
class
CommandListView
(
DatetimeSearchMixin
,
AdminUserRequiredMixin
,
ListView
):
...
...
apps/terminal/views/session.py
View file @
de2416b1
...
...
@@ -10,7 +10,7 @@ from django.conf import settings
from
users.utils
import
AdminUserRequiredMixin
from
common.mixins
import
DatetimeSearchMixin
from
..models
import
Session
,
Command
,
Terminal
from
..backends
import
get_multi_command_store
from
..backends
import
get_multi_command_stor
ag
e
from
..
import
utils
...
...
@@ -19,7 +19,7 @@ __all__ = [
'SessionDetailView'
,
]
command_store
=
get_multi_command_store
()
command_store
=
get_multi_command_stor
ag
e
()
class
SessionListView
(
AdminUserRequiredMixin
,
DatetimeSearchMixin
,
ListView
):
...
...
apps/users/models/group.py
View file @
de2416b1
...
...
@@ -11,7 +11,7 @@ __all__ = ['UserGroup']
class
UserGroup
(
NoDeleteModelMixin
):
id
=
models
.
UUIDField
(
default
=
uuid
.
uuid4
,
primary_key
=
True
)
name
=
models
.
CharField
(
max_length
=
128
,
verbose_name
=
_
(
'Name'
))
name
=
models
.
CharField
(
max_length
=
128
,
unique
=
True
,
verbose_name
=
_
(
'Name'
))
comment
=
models
.
TextField
(
blank
=
True
,
verbose_name
=
_
(
'Comment'
))
date_created
=
models
.
DateTimeField
(
auto_now_add
=
True
,
null
=
True
,
verbose_name
=
_
(
'Date created'
))
...
...
requirements/requirements.txt
View file @
de2416b1
...
...
@@ -40,7 +40,6 @@ itsdangerous==0.24
itypes==1.1.0
Jinja2==2.10
jmespath==0.9.3
jms-es-sdk
kombu==4.0.2
ldap3==2.4
MarkupSafe==1.0
...
...
@@ -62,7 +61,7 @@ pytz==2017.3
PyYAML==3.12
redis==2.10.6
requests==2.18.4
jms-storage==0.0.1
3
jms-storage==0.0.1
7
s3transfer==0.1.13
simplejson==3.13.2
six==1.11.0
...
...
utils/clean_duplicate_user_groups.py
0 → 100644
View file @
de2416b1
#!/usr/bin/python
#
import
os
import
sys
from
collections
import
Counter
import
django
from
django.db.models
import
Count
if
os
.
path
.
exists
(
'../apps'
):
sys
.
path
.
insert
(
0
,
'../apps'
)
elif
os
.
path
.
exists
(
'./apps'
):
sys
.
path
.
insert
(
0
,
'./apps'
)
os
.
environ
.
setdefault
(
"DJANGO_SETTINGS_MODULE"
,
"jumpserver.settings"
)
django
.
setup
()
from
users.models
import
UserGroup
def
clean_group
(
interactive
=
True
):
groups
=
UserGroup
.
objects
.
all
()
groups_name_list
=
groups
.
values_list
(
'name'
,
flat
=
True
)
groups_with_info
=
groups
.
annotate
(
Count
(
'users'
))
\
.
annotate
(
Count
(
'asset_permissions'
))
counter
=
Counter
(
groups_name_list
)
for
name
,
count
in
counter
.
items
():
if
count
==
0
:
continue
groups_duplicate
=
groups_with_info
.
filter
(
name
=
name
)
need_clean_count
=
groups_duplicate
.
count
()
for
group
in
groups_duplicate
:
need_clean
=
True
if
group
.
users__count
>
0
:
need_clean
=
False
elif
group
.
asset_permissions__count
>
0
:
need_clean
=
False
elif
need_clean_count
==
1
:
need_clean
=
False
if
need_clean
:
confirm
=
True
if
interactive
:
confirm
=
False
while
True
:
confirm
=
input
(
"Delete user group <{}>, create at {}? ([y]/n)"
.
format
(
name
,
group
.
date_created
)
)
if
confirm
.
lower
()
==
"y"
:
confirm
=
True
break
elif
confirm
.
lower
()
==
"n"
:
confirm
=
False
break
else
:
print
(
"No valid input"
)
continue
if
confirm
:
group
.
delete
()
print
(
"Delete success: {}"
.
format
(
name
))
need_clean_count
-=
1
else
:
continue
if
__name__
==
'__main__'
:
clean_group
()
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