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
de43980e
Unverified
Commit
de43980e
authored
Aug 31, 2019
by
老广
Committed by
GitHub
Aug 31, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Dev beta2 (#3177)
* [Update] 添加loading * [Update] stash * [Update] 修改permission
parent
d5dcab15
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
227 additions
and
85 deletions
+227
-85
user_asset_list.html
apps/assets/templates/assets/user_asset_list.html
+0
-1
api_urls.py
apps/assets/urls/api_urls.py
+3
-3
utils.py
apps/assets/utils.py
+11
-13
api_urls.py
apps/audits/urls/api_urls.py
+8
-2
api.py
apps/common/api.py
+6
-2
user_group_permission.py
apps/perms/api/user_group_permission.py
+4
-3
user_permission.py
apps/perms/api/user_permission.py
+107
-36
api_urls.py
apps/perms/urls/api_urls.py
+18
-4
asset_permission.py
apps/perms/utils/asset_permission.py
+44
-5
api_urls.py
apps/terminal/urls/api_urls.py
+13
-8
api_urls_v2.py
apps/terminal/urls/api_urls_v2.py
+7
-2
_granted_assets.html
apps/users/templates/users/_granted_assets.html
+6
-4
user_granted_asset.html
apps/users/templates/users/user_granted_asset.html
+0
-1
user_group_granted_asset.html
apps/users/templates/users/user_group_granted_asset.html
+0
-1
No files found.
apps/assets/templates/assets/user_asset_list.html
View file @
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
View file @
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
View file @
de43980e
...
...
@@ -66,19 +66,15 @@ 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
from
orgs.utils
import
tmp
_to_root_org
origin_org
=
get_current_org
()
set_to_root_org
()
with
tmp_to_root_org
():
all_nodes
=
Node
.
objects
.
all
()
origin_org
.
change_to
()
tree
=
cls
()
tree
.
create_node
(
tag
=
''
,
identifier
=
''
)
for
node
in
all_nodes
:
...
...
@@ -86,7 +82,7 @@ class TreeService(Tree):
tag
=
node
.
value
,
identifier
=
node
.
key
,
parent
=
node
.
parent_key
,
)
tree
.
init_assets_async
()
tree
.
init_assets
()
return
tree
def
init_assets_async
(
self
):
...
...
@@ -95,7 +91,6 @@ 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'
)
...
...
@@ -146,12 +141,10 @@ class TreeService(Tree):
return
parent
def
assets
(
self
,
nid
):
with
self
.
mutex
:
assets
=
self
.
nodes_assets_map
[
nid
]
return
assets
def
set_assets
(
self
,
nid
,
assets
):
with
self
.
mutex
:
self
.
nodes_assets_map
[
nid
]
=
assets
def
all_assets
(
self
,
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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,8 +268,14 @@ class AssetPermissionUtilV2:
@timeit
def
get_user_tree
(
self
):
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
(
...
...
@@ -249,7 +286,7 @@ class AssetPermissionUtilV2:
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
self
.
__class__
.
set_user_tree_to_cache
(
self
.
obj_id
,
user_tree
)
return
user_tree
# Todo: 是否可以获取多个资产的系统用户
...
...
@@ -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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
de43980e
...
...
@@ -42,7 +42,6 @@ var showAssetHref = true; // Need input default true
$
(
document
).
ready
(
function
()
{
initTree
();
initTable
();
});
</script>
{% endblock %}
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