Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
gjl2004yn
jumpserver
提交
de43980e
J
jumpserver
项目概览
gjl2004yn
/
jumpserver
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
jumpserver
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
de43980e
编写于
8月 31, 2019
作者:
baltery
提交者:
GitHub
8月 31, 2019
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Dev beta2 (#3177)
* [Update] 添加loading * [Update] stash * [Update] 修改permission
上级
d5dcab15
变更
14
隐藏空白更改
内联
并排
Showing
14 changed file
with
262 addition
and
120 deletion
+262
-120
apps/assets/templates/assets/user_asset_list.html
apps/assets/templates/assets/user_asset_list.html
+0
-1
apps/assets/urls/api_urls.py
apps/assets/urls/api_urls.py
+3
-3
apps/assets/utils.py
apps/assets/utils.py
+33
-35
apps/audits/urls/api_urls.py
apps/audits/urls/api_urls.py
+8
-2
apps/common/api.py
apps/common/api.py
+6
-2
apps/perms/api/user_group_permission.py
apps/perms/api/user_group_permission.py
+4
-3
apps/perms/api/user_permission.py
apps/perms/api/user_permission.py
+107
-36
apps/perms/urls/api_urls.py
apps/perms/urls/api_urls.py
+18
-4
apps/perms/utils/asset_permission.py
apps/perms/utils/asset_permission.py
+57
-18
apps/terminal/urls/api_urls.py
apps/terminal/urls/api_urls.py
+13
-8
apps/terminal/urls/api_urls_v2.py
apps/terminal/urls/api_urls_v2.py
+7
-2
apps/users/templates/users/_granted_assets.html
apps/users/templates/users/_granted_assets.html
+6
-4
apps/users/templates/users/user_granted_asset.html
apps/users/templates/users/user_granted_asset.html
+0
-1
apps/users/templates/users/user_group_granted_asset.html
apps/users/templates/users/user_group_granted_asset.html
+0
-1
未找到文件。
apps/assets/templates/assets/user_asset_list.html
浏览文件 @
de43980e
...
...
@@ -34,7 +34,6 @@ var actions = {
}};
$
(
document
).
ready
(
function
()
{
initTree
();
initTable
();
}).
on
(
'
click
'
,
'
.labels li
'
,
function
()
{
var
val
=
$
(
this
).
text
();
$
(
"
#user_assets_table_filter input
"
).
val
(
val
);
...
...
apps/assets/urls/api_urls.py
浏览文件 @
de43980e
...
...
@@ -51,15 +51,15 @@ urlpatterns = [
path
(
'system-users/<uuid:pk>/auth-info/'
,
api
.
SystemUserAuthInfoApi
.
as_view
(),
name
=
'system-user-auth-info'
),
path
(
'system-users/<uuid:pk>/asset/<uuid:aid>/auth-info/'
,
path
(
'system-users/<uuid:pk>/asset
s
/<uuid:aid>/auth-info/'
,
api
.
SystemUserAssetAuthInfoApi
.
as_view
(),
name
=
'system-user-asset-auth-info'
),
path
(
'system-users/<uuid:pk>/assets/'
,
api
.
SystemUserAssetsListView
.
as_view
(),
name
=
'system-user-assets'
),
path
(
'system-users/<uuid:pk>/push/'
,
api
.
SystemUserPushApi
.
as_view
(),
name
=
'system-user-push'
),
path
(
'system-users/<uuid:pk>/asset/<uuid:aid>/push/'
,
path
(
'system-users/<uuid:pk>/asset
s
/<uuid:aid>/push/'
,
api
.
SystemUserPushToAssetApi
.
as_view
(),
name
=
'system-user-push-to-asset'
),
path
(
'system-users/<uuid:pk>/asset/<uuid:aid>/test/'
,
path
(
'system-users/<uuid:pk>/asset
s
/<uuid:aid>/test/'
,
api
.
SystemUserTestAssetConnectivityApi
.
as_view
(),
name
=
'system-user-test-to-asset'
),
path
(
'system-users/<uuid:pk>/connective/'
,
api
.
SystemUserTestConnectiveApi
.
as_view
(),
name
=
'system-user-connective'
),
...
...
apps/assets/utils.py
浏览文件 @
de43980e
...
...
@@ -66,27 +66,23 @@ class TreeService(Tree):
super
().
__init__
(
*
args
,
**
kwargs
)
self
.
nodes_assets_map
=
defaultdict
(
set
)
self
.
all_nodes_assets_map
=
{}
self
.
mutex
=
threading
.
Lock
()
@
classmethod
@
timeit
def
new
(
cls
):
from
.models
import
Node
from
orgs.utils
import
get_current_org
,
set_to_root_org
origin_org
=
get_current_org
()
set_to_root_org
()
all_nodes
=
Node
.
objects
.
all
()
origin_org
.
change_to
()
tree
=
cls
()
tree
.
create_node
(
tag
=
''
,
identifier
=
''
)
for
node
in
all_nodes
:
tree
.
create_node
(
tag
=
node
.
value
,
identifier
=
node
.
key
,
parent
=
node
.
parent_key
,
)
tree
.
init_assets_async
()
from
orgs.utils
import
tmp_to_root_org
with
tmp_to_root_org
():
all_nodes
=
Node
.
objects
.
all
()
tree
=
cls
()
tree
.
create_node
(
tag
=
''
,
identifier
=
''
)
for
node
in
all_nodes
:
tree
.
create_node
(
tag
=
node
.
value
,
identifier
=
node
.
key
,
parent
=
node
.
parent_key
,
)
tree
.
init_assets
()
return
tree
def
init_assets_async
(
self
):
...
...
@@ -95,17 +91,16 @@ class TreeService(Tree):
def
init_assets
(
self
):
from
orgs.utils
import
get_current_org
,
set_to_root_org
with
self
.
mutex
:
origin_org
=
get_current_org
()
set_to_root_org
()
queryset
=
Asset
.
objects
.
all
().
valid
().
values_list
(
'id'
,
'nodes__key'
)
if
origin_org
:
origin_org
.
change_to
()
for
asset_id
,
key
in
queryset
:
if
not
key
:
continue
self
.
nodes_assets_map
[
key
].
add
(
asset_id
)
origin_org
=
get_current_org
()
set_to_root_org
()
queryset
=
Asset
.
objects
.
all
().
valid
().
values_list
(
'id'
,
'nodes__key'
)
if
origin_org
:
origin_org
.
change_to
()
for
asset_id
,
key
in
queryset
:
if
not
key
:
continue
self
.
nodes_assets_map
[
key
].
add
(
asset_id
)
def
all_children
(
self
,
nid
,
with_self
=
True
,
deep
=
False
):
children_ids
=
self
.
expand_tree
(
nid
)
...
...
@@ -146,13 +141,11 @@ class TreeService(Tree):
return
parent
def
assets
(
self
,
nid
):
with
self
.
mutex
:
assets
=
self
.
nodes_assets_map
[
nid
]
return
assets
assets
=
self
.
nodes_assets_map
[
nid
]
return
assets
def
set_assets
(
self
,
nid
,
assets
):
with
self
.
mutex
:
self
.
nodes_assets_map
[
nid
]
=
assets
self
.
nodes_assets_map
[
nid
]
=
assets
def
all_assets
(
self
,
nid
):
assets
=
self
.
all_nodes_assets_map
.
get
(
nid
)
...
...
@@ -186,12 +179,17 @@ class TreeService(Tree):
self
.
safe_add_ancestors
(
ancestors
)
parent
=
self
.
get_node
(
parent_id
)
print
(
"Add node: {} {}"
.
format
(
node
.
identifier
,
parent
.
identifier
))
# 如果当前节点已再树中,则移动当前节点到父节点中
# 这个是由于 当前节点放到了二级节点中
if
self
.
contains
(
node
.
identifier
):
self
.
move_node
(
node
.
identifier
,
parent
.
identifier
)
else
:
self
.
add_node
(
node
,
parent
)
#
# def __getstate__(self):
# self.mutex = None
# return self.__dict__
#
# def __setstate__(self, state):
# self.__dict__ = state
# self.mutex = threading.Lock()
apps/audits/urls/api_urls.py
浏览文件 @
de43980e
# ~*~ coding: utf-8 ~*~
from
__future__
import
unicode_literals
from
django.
conf.urls
import
url
from
django.
urls.conf
import
re_path
from
rest_framework.routers
import
DefaultRouter
from
common
import
api
as
capi
from
..
import
api
app_name
=
"audits"
router
=
DefaultRouter
()
router
.
register
(
r
'ftp-log'
,
api
.
FTPLogViewSet
,
'ftp-log'
)
router
.
register
(
r
'ftp-log
s
'
,
api
.
FTPLogViewSet
,
'ftp-log'
)
urlpatterns
=
[
]
old_version_urlpatterns
=
[
re_path
(
'(?P<resource>ftp-log)/.*'
,
capi
.
redirect_plural_name_api
)
]
urlpatterns
+=
router
.
urls
apps/common/api.py
浏览文件 @
de43980e
...
...
@@ -12,11 +12,14 @@ from rest_framework import generics, serializers
from
.http
import
HttpResponseTemporaryRedirect
from
.const
import
KEY_CACHE_RESOURCES_ID
from
.utils
import
get_logger
__all__
=
[
'LogTailApi'
,
'ResourcesIDCacheApi'
,
]
logger
=
get_logger
(
__file__
)
class
OutputSerializer
(
serializers
.
Serializer
):
output
=
serializers
.
CharField
()
...
...
@@ -93,6 +96,7 @@ class ResourcesIDCacheApi(APIView):
@
csrf_exempt
def
redirect_plural_name_api
(
request
,
*
args
,
**
kwargs
):
resource
=
kwargs
.
get
(
"resource"
,
""
)
full_path
=
request
.
get_full_path
()
full_path
=
full_path
.
replace
(
resource
,
resource
+
"s"
,
1
)
org_full_path
=
request
.
get_full_path
()
full_path
=
org_full_path
.
replace
(
resource
,
resource
+
"s"
,
1
)
logger
.
debug
(
"Redirect {} => {}"
.
format
(
org_full_path
,
full_path
))
return
HttpResponseTemporaryRedirect
(
full_path
)
apps/perms/api/user_group_permission.py
浏览文件 @
de43980e
...
...
@@ -10,9 +10,10 @@ from . import user_permission as uapi
__all__
=
[
'UserGroupGrantedAssetsApi'
,
'UserGroupGrantedNodesApi'
,
'UserGroupGrantedNodeAssetsApi'
,
'UserGroupGrantedNodeChildrenApi'
,
'UserGroupGrantedNodeChildrenAsTreeApi'
,
'UserGroupGrantedNodesWithAssetsAsTreeApi'
,
'UserGroupGrantedNodeChildrenAsTreeApi'
,
'UserGroupGrantedNodeChildrenWithAssetsAsTreeApi'
,
'UserGroupGrantedAssetSystemUsersApi'
,
# 'UserGroupGrantedNode
s
WithAssetsAsTreeApi',
# 'UserGroupGrantedNode
Children
WithAssetsAsTreeApi',
]
...
...
@@ -45,7 +46,7 @@ class UserGroupGrantedNodeChildrenAsTreeApi(UserGroupPermissionMixin, uapi.UserG
pass
class
UserGroupGrantedNode
sWithAssetsAsTreeApi
(
UserGroupPermissionMixin
,
uapi
.
UserGrantedNodes
WithAssetsAsTreeApi
):
class
UserGroupGrantedNode
ChildrenWithAssetsAsTreeApi
(
UserGroupPermissionMixin
,
uapi
.
UserGrantedNodeChildren
WithAssetsAsTreeApi
):
pass
...
...
apps/perms/api/user_permission.py
浏览文件 @
de43980e
...
...
@@ -23,12 +23,19 @@ from ..models import Action
logger
=
get_logger
(
__name__
)
__all__
=
[
'UserGrantedAssetsApi'
,
'UserGrantedNodesApi'
,
'UserGrantedAssetsApi'
,
'UserGrantedAssetsAsTreeApi'
,
'UserGrantedNodeAssetsApi'
,
'UserGrantedNodesApi'
,
'UserGrantedNodesAsTreeApi'
,
'UserGrantedNodesWithAssetsAsTreeApi'
,
'UserGrantedNodeChildrenApi'
,
'UserGrantedNodeChildrenAsTreeApi'
,
'UserGrantedNodeChildrenWithAssetsAsTreeApi'
,
'RefreshAssetPermissionCacheApi'
,
'UserGrantedAssetSystemUsersApi'
,
'ValidateUserAssetPermissionApi'
,
'UserGrantedNodesWithAssetsAsTreeApi'
,
'GetUserAssetPermissionActionsApi'
,
'RefreshAssetPermissionCacheApi'
,
'UserGrantedAssetSystemUsersApi'
,
'UserGrantedNodeChildrenAsTreeApi'
,
'UserGrantedNodesWithAssetsAsTreeApi'
,
'GetUserAssetPermissionActionsApi'
,
]
...
...
@@ -58,6 +65,66 @@ class UserPermissionMixin:
return
super
().
get_permissions
()
class
UserNodePermissionMixin
(
UserPermissionMixin
):
util
=
None
def
initial
(
self
,
*
args
,
**
kwargs
):
super
().
initial
(
*
args
,
*
kwargs
)
self
.
util
=
AssetPermissionUtilV2
(
self
.
obj
)
class
UserNodeTreeMixin
:
serializer_class
=
TreeNodeSerializer
nodes_only_fields
=
ParserNode
.
nodes_only_fields
tree
=
None
def
parse_nodes_to_queryset
(
self
,
nodes
):
nodes
=
nodes
.
only
(
*
self
.
nodes_only_fields
)
_queryset
=
[]
tree
=
self
.
util
.
get_user_tree
()
for
node
in
nodes
:
assets_amount
=
tree
.
assets_amount
(
node
.
key
)
if
assets_amount
==
0
:
continue
node
.
_assets_amount
=
assets_amount
data
=
ParserNode
.
parse_node_to_tree_node
(
node
)
_queryset
.
append
(
data
)
return
_queryset
def
get_serializer_queryset
(
self
,
queryset
):
queryset
=
self
.
parse_nodes_to_queryset
(
queryset
)
return
queryset
def
get_serializer
(
self
,
queryset
,
many
=
True
,
**
kwargs
):
queryset
=
self
.
get_serializer_queryset
(
queryset
)
queryset
.
sort
()
return
super
().
get_serializer
(
queryset
,
many
=
many
,
**
kwargs
)
class
UserAssetTreeMixin
:
serializer_class
=
TreeNodeSerializer
nodes_only_fields
=
ParserNode
.
assets_only_fields
@
staticmethod
def
parse_assets_to_queryset
(
assets
,
node
):
_queryset
=
[]
for
asset
in
assets
:
data
=
ParserNode
.
parse_asset_to_tree_node
(
node
,
asset
)
_queryset
.
append
(
data
)
return
_queryset
def
get_serializer_queryset
(
self
,
queryset
):
queryset
=
queryset
.
only
(
*
self
.
nodes_only_fields
)
_queryset
=
self
.
parse_assets_to_queryset
(
queryset
,
None
)
return
_queryset
def
get_serializer
(
self
,
queryset
,
many
=
True
,
**
kwargs
):
queryset
=
self
.
get_serializer_queryset
(
queryset
)
queryset
.
sort
()
return
super
().
get_serializer
(
queryset
,
many
=
many
,
**
kwargs
)
class
UserGrantedAssetsApi
(
UserPermissionMixin
,
ListAPIView
):
permission_classes
=
(
IsOrgAdminOrAppUser
,)
serializer_class
=
serializers
.
AssetGrantedSerializer
...
...
@@ -89,6 +156,10 @@ class UserGrantedAssetsApi(UserPermissionMixin, ListAPIView):
return
queryset
class
UserGrantedAssetsAsTreeApi
(
UserAssetTreeMixin
,
UserGrantedAssetsApi
):
pass
class
UserGrantedNodeAssetsApi
(
UserGrantedAssetsApi
):
def
get_queryset
(
self
):
node_id
=
self
.
kwargs
.
get
(
"node_id"
)
...
...
@@ -100,18 +171,13 @@ class UserGrantedNodeAssetsApi(UserGrantedAssetsApi):
return
queryset
class
UserGrantedNodesApi
(
UserPermissionMixin
,
ListAPIView
):
class
UserGrantedNodesApi
(
User
Node
PermissionMixin
,
ListAPIView
):
"""
查询用户授权的所有节点的API
"""
permission_classes
=
(
IsOrgAdminOrAppUser
,)
serializer_class
=
serializers
.
NodeGrantedSerializer
only_fields
=
NodeSerializer
.
Meta
.
only_fields
util
=
None
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
self
.
util
=
AssetPermissionUtilV2
(
self
.
obj
)
return
super
().
get
(
request
,
*
args
,
**
kwargs
)
nodes_only_fields
=
NodeSerializer
.
Meta
.
only_fields
def
get_serializer_context
(
self
):
context
=
super
().
get_serializer_context
()
...
...
@@ -120,21 +186,35 @@ class UserGrantedNodesApi(UserPermissionMixin, ListAPIView):
def
get_queryset
(
self
):
node_keys
=
self
.
util
.
get_nodes
()
queryset
=
Node
.
objects
.
filter
(
key__in
=
node_keys
)
queryset
=
Node
.
objects
.
filter
(
key__in
=
node_keys
)
\
.
only
(
*
self
.
nodes_only_fields
)
return
queryset
class
UserGrantedNodesAsTreeApi
(
UserNodeTreeMixin
,
UserGrantedNodesApi
):
pass
class
UserGrantedNodesWithAssetsAsTreeApi
(
UserGrantedNodesAsTreeApi
):
def
get_serializer_queryset
(
self
,
queryset
):
_queryset
=
super
().
get_serializer_queryset
(
queryset
)
for
node
in
queryset
:
assets
=
self
.
util
.
get_nodes_assets
(
node
)
_queryset
.
extend
(
UserAssetTreeMixin
.
parse_assets_to_queryset
(
assets
,
node
)
)
return
_queryset
class
UserGrantedNodeChildrenApi
(
UserGrantedNodesApi
):
node
=
None
util
=
None
tree
=
None
root_keys
=
None
root_keys
=
None
# 如果是第一次访问,则需要把二级节点添加进去,这个 roots_keys
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
key
=
self
.
request
.
query_params
.
get
(
"key"
)
pk
=
self
.
request
.
query_params
.
get
(
"id"
)
system_user_id
=
self
.
request
.
query_params
.
get
(
"system_user"
)
self
.
util
=
AssetPermissionUtilV2
(
self
.
obj
)
if
system_user_id
:
self
.
util
.
filter_permissions
(
system_users
=
system_user_id
)
self
.
tree
=
self
.
util
.
get_user_tree
()
...
...
@@ -161,26 +241,16 @@ class UserGrantedNodeChildrenApi(UserGrantedNodesApi):
return
queryset
class
UserGrantedNodeChildrenAsTreeApi
(
UserGrantedNodeChildrenApi
):
serializer_class
=
TreeNodeSerializer
only_fields
=
ParserNode
.
nodes_only_fields
def
get_queryset
(
self
):
nodes
=
super
().
get_queryset
()
queryset
=
[]
for
node
in
nodes
:
node
.
_assets_amount
=
self
.
tree
.
assets_amount
(
node
.
key
)
data
=
ParserNode
.
parse_node_to_tree_node
(
node
)
queryset
.
append
(
data
)
return
queryset
class
UserGrantedNodeChildrenAsTreeApi
(
UserNodeTreeMixin
,
UserGrantedNodeChildrenApi
):
pass
class
UserGrantedNode
s
WithAssetsAsTreeApi
(
UserGrantedNodeChildrenAsTreeApi
):
class
UserGrantedNode
Children
WithAssetsAsTreeApi
(
UserGrantedNodeChildrenAsTreeApi
):
nodes_only_fields
=
ParserNode
.
nodes_only_fields
assets_only_fields
=
ParserNode
.
assets_only_fields
def
get_
queryset
(
self
):
queryset
=
super
().
get_queryset
(
)
def
get_
serializer_queryset
(
self
,
queryset
):
_queryset
=
super
().
get_serializer_queryset
(
queryset
)
nodes
=
[]
if
self
.
node
:
nodes
.
append
(
self
.
node
)
...
...
@@ -188,12 +258,13 @@ class UserGrantedNodesWithAssetsAsTreeApi(UserGrantedNodeChildrenAsTreeApi):
nodes
=
Node
.
objects
.
filter
(
key__in
=
self
.
root_keys
)
for
node
in
nodes
:
assets
=
self
.
util
.
get_nodes_assets
(
node
).
only
(
*
self
.
assets_only_fields
)
for
asset
in
assets
:
data
=
ParserNode
.
parse_asset_to_tree_node
(
node
,
asset
)
queryset
.
append
(
data
)
queryset
=
sorted
(
queryset
)
return
queryset
assets
=
self
.
util
.
get_nodes_assets
(
node
).
only
(
*
self
.
assets_only_fields
)
_queryset
.
extend
(
UserAssetTreeMixin
.
parse_assets_to_queryset
(
assets
,
node
)
)
return
_queryset
class
GetUserAssetPermissionActionsApi
(
RetrieveAPIView
):
...
...
apps/perms/urls/api_urls.py
浏览文件 @
de43980e
...
...
@@ -17,16 +17,34 @@ asset_permission_urlpatterns = [
path
(
'users/<uuid:pk>/assets/'
,
api
.
UserGrantedAssetsApi
.
as_view
(),
name
=
'user-assets'
),
path
(
'users/assets/'
,
api
.
UserGrantedAssetsApi
.
as_view
(),
name
=
'my-assets'
),
# Assets as tree
path
(
'users/<uuid:pk>/assets/tree/'
,
api
.
UserGrantedAssetsAsTreeApi
.
as_view
(),
name
=
'user-assets-as-tree'
),
path
(
'users/assets/tree/'
,
api
.
UserGrantedAssetsAsTreeApi
.
as_view
(),
name
=
'my-assets-as-tree'
),
# Nodes
path
(
'users/<uuid:pk>/nodes/'
,
api
.
UserGrantedNodesApi
.
as_view
(),
name
=
'user-nodes'
),
path
(
'users/nodes/'
,
api
.
UserGrantedNodesApi
.
as_view
(),
name
=
'my-nodes'
),
# Node children
path
(
'users/<uuid:pk>/nodes/children/'
,
api
.
UserGrantedNodesApi
.
as_view
(),
name
=
'user-nodes-children'
),
path
(
'users/nodes/children/'
,
api
.
UserGrantedNodesApi
.
as_view
(),
name
=
'my-nodes-children'
),
# Node as tree
path
(
'users/<uuid:pk>/nodes/tree/'
,
api
.
UserGrantedNodesAsTreeApi
.
as_view
(),
name
=
'user-nodes-as-tree'
),
path
(
'users/nodes/tree/'
,
api
.
UserGrantedNodesAsTreeApi
.
as_view
(),
name
=
'my-nodes-as-tree'
),
# Node with assets as tree
path
(
'users/<uuid:pk>/nodes-with-assets/tree/'
,
api
.
UserGrantedNodesWithAssetsAsTreeApi
.
as_view
(),
name
=
'user-nodes-with-assets-as-tree'
),
path
(
'users/nodes-with-assets/tree/'
,
api
.
UserGrantedNodesWithAssetsAsTreeApi
.
as_view
(),
name
=
'my-nodes-with-assets-as-tree'
),
# Node children as tree
path
(
'users/<uuid:pk>/nodes/children/tree/'
,
api
.
UserGrantedNodeChildrenAsTreeApi
.
as_view
(),
name
=
'user-nodes-children-as-tree'
),
path
(
'users/nodes/children/tree/'
,
api
.
UserGrantedNodeChildrenAsTreeApi
.
as_view
(),
name
=
'my-nodes-children-as-tree'
),
# Node children with assets as tree
path
(
'users/<uuid:pk>/nodes/children-with-assets/tree/'
,
api
.
UserGrantedNodeChildrenWithAssetsAsTreeApi
.
as_view
(),
name
=
'user-nodes-children-with-assets-as-tree'
),
path
(
'users/nodes/children-with-assets/tree/'
,
api
.
UserGrantedNodeChildrenWithAssetsAsTreeApi
.
as_view
(),
name
=
'my-nodes-children-with-assets-as-tree'
),
# Node assets
path
(
'users/<uuid:pk>/nodes/<uuid:node_id>/assets/'
,
api
.
UserGrantedNodeAssetsApi
.
as_view
(),
name
=
'user-node-assets'
),
path
(
'users/nodes/<uuid:node_id>/assets/'
,
api
.
UserGrantedNodeAssetsApi
.
as_view
(),
name
=
'my-node-assets'
),
...
...
@@ -35,10 +53,6 @@ asset_permission_urlpatterns = [
path
(
'users/<uuid:pk>/assets/<uuid:asset_id>/system-users/'
,
api
.
UserGrantedAssetSystemUsersApi
.
as_view
(),
name
=
'user-asset-system-users'
),
path
(
'users/assets/<uuid:asset_id>/system-users/'
,
api
.
UserGrantedAssetSystemUsersApi
.
as_view
(),
name
=
'my-asset-system-users'
),
# Node assets as tree
path
(
'users/<uuid:pk>/nodes/children-with-assets/tree/'
,
api
.
UserGrantedNodesWithAssetsAsTreeApi
.
as_view
(),
name
=
'user-nodes-children-with-assets-as-tree'
),
path
(
'users/nodes/children-with-assets/tree/'
,
api
.
UserGrantedNodesWithAssetsAsTreeApi
.
as_view
(),
name
=
'my-nodes-children-with-assets-as-tree'
),
# 查询某个用户组授权的资产和资产组
path
(
'user-groups/<uuid:pk>/assets/'
,
api
.
UserGroupGrantedAssetsApi
.
as_view
(),
name
=
'user-group-assets'
),
path
(
'user-groups/<uuid:pk>/nodes/'
,
api
.
UserGroupGrantedNodesApi
.
as_view
(),
name
=
'user-group-nodes'
),
...
...
apps/perms/utils/asset_permission.py
浏览文件 @
de43980e
# coding: utf-8
import
pickle
import
threading
from
collections
import
defaultdict
from
functools
import
reduce
from
django.core.cache
import
cache
from
django.db.models
import
Q
from
django.conf
import
settings
...
...
@@ -12,7 +15,6 @@ from common.tree import TreeNode
from
assets.utils
import
TreeService
from
..models
import
AssetPermission
from
..hands
import
Node
,
Asset
,
SystemUser
from
..
import
const
logger
=
get_logger
(
__file__
)
...
...
@@ -69,9 +71,12 @@ class AssetPermissionUtilV2:
'id'
,
'hostname'
,
'ip'
,
"platform"
,
"domain_id"
,
'comment'
,
'is_active'
,
'os'
,
'org_id'
)
user_tree_cache_key
=
'USER_PERM_TREE_{}'
user_tree_cache_ttl
=
3600
def
__init__
(
self
,
obj
,
cache_policy
=
'0'
):
self
.
object
=
obj
self
.
cache_policy
=
cache_policy
self
.
obj_id
=
str
(
obj
.
id
)
self
.
_permissions
=
None
self
.
_permissions_id
=
None
# 标记_permission的唯一值
...
...
@@ -84,6 +89,7 @@ class AssetPermissionUtilV2:
self
.
_nodes_direct
=
None
self
.
_user_tree
=
None
self
.
full_tree
=
Node
.
tree
()
self
.
mutex
=
threading
.
Lock
()
@
staticmethod
def
change_org_if_need
():
...
...
@@ -103,6 +109,31 @@ class AssetPermissionUtilV2:
def
filter_permissions
(
self
,
**
filters
):
self
.
_permissions
=
self
.
permissions
.
filter
(
**
filters
)
@
classmethod
def
get_user_tree_from_cache
(
cls
,
obj_id
):
return
None
key
=
cls
.
user_tree_cache_key
.
format
(
obj_id
)
data
=
cache
.
get
(
key
)
if
not
data
:
return
None
user_tree
=
pickle
.
loads
(
data
)
return
user_tree
@
classmethod
def
expire_user_tree_cache
(
cls
,
obj_id
):
if
obj_id
==
'all'
:
key
=
cls
.
user_tree_cache_key
.
format
(
'*'
)
cache
.
delete_pattern
(
key
)
else
:
key
=
cls
.
user_tree_cache_key
.
format
(
obj_id
)
cache
.
delete
(
key
)
@
classmethod
def
set_user_tree_to_cache
(
cls
,
obj_id
,
user_tree
):
data
=
pickle
.
dumps
(
user_tree
)
key
=
cls
.
user_tree_cache_key
.
format
(
obj_id
)
cache
.
set
(
key
,
data
,
cls
.
user_tree_cache_ttl
)
@
property
def
user_tree
(
self
):
return
self
.
get_user_tree
()
...
...
@@ -237,20 +268,26 @@ class AssetPermissionUtilV2:
@
timeit
def
get_user_tree
(
self
):
if
self
.
_user_tree
:
return
self
.
_user_tree
user_tree
=
TreeService
()
full_tree_root
=
self
.
full_tree
.
root_node
()
user_tree
.
create_node
(
tag
=
full_tree_root
.
tag
,
identifier
=
full_tree_root
.
identifier
)
self
.
add_direct_nodes_to_user_tree
(
user_tree
)
self
.
add_single_assets_node_to_user_tree
(
user_tree
)
self
.
parse_user_tree_to_full_tree
(
user_tree
)
self
.
add_empty_node_if_need
(
user_tree
)
self
.
_user_tree
=
user_tree
return
user_tree
with
self
.
mutex
:
if
self
.
_user_tree
:
return
self
.
_user_tree
print
(
id
(
self
),
self
.
_user_tree
)
user_tree
=
self
.
__class__
.
get_user_tree_from_cache
(
self
.
obj_id
)
if
user_tree
:
self
.
_user_tree
=
user_tree
return
user_tree
user_tree
=
TreeService
()
full_tree_root
=
self
.
full_tree
.
root_node
()
user_tree
.
create_node
(
tag
=
full_tree_root
.
tag
,
identifier
=
full_tree_root
.
identifier
)
self
.
add_direct_nodes_to_user_tree
(
user_tree
)
self
.
add_single_assets_node_to_user_tree
(
user_tree
)
self
.
parse_user_tree_to_full_tree
(
user_tree
)
self
.
add_empty_node_if_need
(
user_tree
)
self
.
__class__
.
set_user_tree_to_cache
(
self
.
obj_id
,
user_tree
)
return
user_tree
# Todo: 是否可以获取多个资产的系统用户
def
get_asset_system_users_with_actions
(
self
,
asset
):
...
...
@@ -401,15 +438,17 @@ class ParserNode:
@
staticmethod
def
parse_asset_to_tree_node
(
node
,
asset
):
icon_skin
=
'file'
if
asset
.
platform
.
lower
()
==
'windows'
:
platform
=
asset
.
platform
.
lower
()
if
platform
==
'windows'
:
icon_skin
=
'windows'
elif
asset
.
platform
.
lower
()
==
'linux'
:
elif
platform
==
'linux'
:
icon_skin
=
'linux'
parent_id
=
node
.
key
if
node
else
''
data
=
{
'id'
:
str
(
asset
.
id
),
'name'
:
asset
.
hostname
,
'title'
:
asset
.
ip
,
'pId'
:
node
.
key
,
'pId'
:
parent_id
,
'isParent'
:
False
,
'open'
:
False
,
'iconSkin'
:
icon_skin
,
...
...
apps/terminal/urls/api_urls.py
浏览文件 @
de43980e
...
...
@@ -2,20 +2,21 @@
# -*- coding: utf-8 -*-
#
from
django.urls
import
path
,
include
from
django.urls
import
path
,
include
,
re_path
from
rest_framework_bulk.routes
import
BulkRouter
from
common
import
api
as
capi
from
..
import
api
app_name
=
'terminal'
router
=
BulkRouter
()
router
.
register
(
r
'sessions'
,
api
.
SessionViewSet
,
'session'
)
router
.
register
(
r
'terminal/(?P<terminal>[a-zA-Z0-9\-]{36})?/?status'
,
api
.
StatusViewSet
,
'terminal-status'
)
router
.
register
(
r
'terminal/(?P<terminal>[a-zA-Z0-9\-]{36})?/?sessions'
,
api
.
SessionViewSet
,
'terminal-sessions'
)
router
.
register
(
r
'terminal'
,
api
.
TerminalViewSet
,
'terminal'
)
router
.
register
(
r
'terminal
s
/(?P<terminal>[a-zA-Z0-9\-]{36})?/?status'
,
api
.
StatusViewSet
,
'terminal-status'
)
router
.
register
(
r
'terminal
s
/(?P<terminal>[a-zA-Z0-9\-]{36})?/?sessions'
,
api
.
SessionViewSet
,
'terminal-sessions'
)
router
.
register
(
r
'terminal
s
'
,
api
.
TerminalViewSet
,
'terminal'
)
router
.
register
(
r
'tasks'
,
api
.
TaskViewSet
,
'tasks'
)
router
.
register
(
r
'command'
,
api
.
CommandViewSet
,
'command'
)
router
.
register
(
r
'command
s
'
,
api
.
CommandViewSet
,
'command'
)
router
.
register
(
r
'status'
,
api
.
StatusViewSet
,
'status'
)
urlpatterns
=
[
...
...
@@ -23,9 +24,9 @@ urlpatterns = [
api
.
SessionReplayViewSet
.
as_view
({
'get'
:
'retrieve'
,
'post'
:
'create'
}),
name
=
'session-replay'
),
path
(
'tasks/kill-session/'
,
api
.
KillSessionAPI
.
as_view
(),
name
=
'kill-session'
),
path
(
'terminal/<uuid:terminal>/access-key/'
,
api
.
TerminalTokenApi
.
as_view
(),
path
(
'terminal
s
/<uuid:terminal>/access-key/'
,
api
.
TerminalTokenApi
.
as_view
(),
name
=
'terminal-access-key'
),
path
(
'terminal/config/'
,
api
.
TerminalConfig
.
as_view
(),
name
=
'terminal-config'
),
path
(
'terminal
s
/config/'
,
api
.
TerminalConfig
.
as_view
(),
name
=
'terminal-config'
),
path
(
'commands/export/'
,
api
.
CommandExportApi
.
as_view
(),
name
=
"command-export"
)
# v2: get session's replay
# path('v2/sessions/<uuid:pk>/replay/',
...
...
@@ -33,7 +34,11 @@ urlpatterns = [
# name='session-replay-v2'),
]
urlpatterns
+=
router
.
urls
old_version_urlpatterns
=
[
re_path
(
'(?P<resource>terminal|command)/.*'
,
capi
.
redirect_plural_name_api
)
]
urlpatterns
+=
router
.
urls
+
old_version_urlpatterns
apps/terminal/urls/api_urls_v2.py
浏览文件 @
de43980e
...
...
@@ -2,15 +2,16 @@
# -*- coding: utf-8 -*-
#
from
django.urls
import
path
from
django.urls
import
path
,
re_path
from
rest_framework_bulk.routes
import
BulkRouter
from
common
import
api
as
capi
from
..
import
api_v2
as
api
app_name
=
'terminal'
router
=
BulkRouter
()
router
.
register
(
r
'terminal'
,
api
.
TerminalViewSet
,
'terminal'
)
router
.
register
(
r
'terminal
s
'
,
api
.
TerminalViewSet
,
'terminal'
)
urlpatterns
=
[
...
...
@@ -18,4 +19,8 @@ urlpatterns = [
name
=
'terminal-registration'
)
]
old_version_urlpatterns
=
[
re_path
(
'(?P<resource>terminal)/.*'
,
capi
.
redirect_plural_name_api
)
]
urlpatterns
+=
router
.
urls
apps/users/templates/users/_granted_assets.html
浏览文件 @
de43980e
...
...
@@ -108,7 +108,7 @@ function onSelected(event, treeNode) {
}
function
initTree
()
{
function
initTree
(
refresh
)
{
var
setting
=
{
view
:
{
dblClickExpand
:
false
,
...
...
@@ -131,11 +131,13 @@ function initTree() {
};
$
.
get
(
treeUrl
,
function
(
data
,
status
)
{
$
.
fn
.
zTree
.
init
(
$
(
"
#assetTree
"
),
setting
,
data
);
zTree
=
$
.
fn
.
zTree
.
getZTreeObj
(
"
assetTree
"
);
zTree
=
$
.
fn
.
zTree
.
init
(
$
(
"
#assetTree
"
),
setting
,
data
);
if
(
!
refresh
)
{
initTable
();
}
rootNodeAddDom
(
zTree
,
function
()
{
treeUrl
=
setUrlParam
(
treeUrl
,
'
cache_policy
'
,
'
2
'
);
initTree
();
initTree
(
true
);
});
});
}
...
...
apps/users/templates/users/user_granted_asset.html
浏览文件 @
de43980e
...
...
@@ -39,7 +39,6 @@ var systemUsersUrl = "{% url 'api-perms:user-asset-system-users' pk=object.id as
$
(
document
).
ready
(
function
()
{
initTree
();
initTable
();
});
</script>
{% endblock %}
apps/users/templates/users/user_group_granted_asset.html
浏览文件 @
de43980e
...
...
@@ -42,7 +42,6 @@ var showAssetHref = true; // Need input default true
$
(
document
).
ready
(
function
()
{
initTree
();
initTable
();
});
</script>
{% endblock %}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录