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
ae690050
Commit
ae690050
authored
Jul 01, 2019
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Stash
parent
8f699fa3
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
236 additions
and
205 deletions
+236
-205
system_user.py
apps/assets/serializers/system_user.py
+1
-6
utils.py
apps/assets/utils.py
+17
-9
asset_permission.py
apps/perms/api/asset_permission.py
+2
-1
user_permission.py
apps/perms/api/user_permission.py
+7
-2
asset_permission.py
apps/perms/forms/asset_permission.py
+2
-2
0006_auto_20190628_1921.py
apps/perms/migrations/0006_auto_20190628_1921.py
+1
-1
0007_remove_assetpermission_actions.py
apps/perms/migrations/0007_remove_assetpermission_actions.py
+5
-0
asset_permission.py
apps/perms/models/asset_permission.py
+27
-20
asset_permission.py
apps/perms/serializers/asset_permission.py
+2
-2
asset_permission_list.html
apps/perms/templates/perms/asset_permission_list.html
+3
-3
asset_permission.py
apps/perms/utils/asset_permission.py
+169
-123
test_asset_permission.py
apps/perms/utils/test_asset_permission.py
+0
-36
No files found.
apps/assets/serializers/system_user.py
View file @
ae690050
...
@@ -50,19 +50,14 @@ class AssetSystemUserSerializer(serializers.ModelSerializer):
...
@@ -50,19 +50,14 @@ class AssetSystemUserSerializer(serializers.ModelSerializer):
"""
"""
查看授权的资产系统用户的数据结构,这个和AssetSerializer不同,字段少
查看授权的资产系统用户的数据结构,这个和AssetSerializer不同,字段少
"""
"""
actions
=
serializers
.
SerializerMethodField
()
class
Meta
:
class
Meta
:
model
=
SystemUser
model
=
SystemUser
fields
=
(
fields
=
(
'id'
,
'name'
,
'username'
,
'priority'
,
'id'
,
'name'
,
'username'
,
'priority'
,
'protocol'
,
'comment'
,
'login_mode'
,
'actions'
,
'protocol'
,
'comment'
,
'login_mode'
,
)
)
@staticmethod
def
get_actions
(
obj
):
return
[
action
.
name
for
action
in
obj
.
actions
]
class
SystemUserSimpleSerializer
(
serializers
.
ModelSerializer
):
class
SystemUserSimpleSerializer
(
serializers
.
ModelSerializer
):
"""
"""
...
...
apps/assets/utils.py
View file @
ae690050
...
@@ -54,17 +54,19 @@ class NodeUtil:
...
@@ -54,17 +54,19 @@ class NodeUtil:
def
sorted_by
(
node
):
def
sorted_by
(
node
):
return
[
int
(
i
)
for
i
in
node
.
key
.
split
(
':'
)]
return
[
int
(
i
)
for
i
in
node
.
key
.
split
(
':'
)]
def
get_
all_nodes
(
self
):
def
get_
queryset
(
self
):
all_nodes
=
Node
.
objects
.
all
()
all_nodes
=
Node
.
objects
.
all
()
if
self
.
with_assets_amount
:
if
self
.
with_assets_amount
:
now
=
time
.
time
()
all_nodes
=
all_nodes
.
prefetch_related
(
all_nodes
=
all_nodes
.
prefetch_related
(
Prefetch
(
'assets'
,
queryset
=
Asset
.
objects
.
all
()
.
only
(
'id'
))
Prefetch
(
'assets'
,
queryset
=
Asset
.
objects
.
all
()
.
only
(
'id'
))
)
)
all_nodes
=
list
(
all_nodes
)
all_nodes
=
list
(
all_nodes
)
for
node
in
all_nodes
:
for
node
in
all_nodes
:
node
.
_assets
=
set
(
node
.
assets
.
all
())
node
.
_assets
=
set
(
node
.
assets
.
all
())
all_nodes
=
sorted
(
all_nodes
,
key
=
self
.
sorted_by
)
return
all_nodes
def
get_all_nodes
(
self
):
all_nodes
=
sorted
(
self
.
get_queryset
(),
key
=
self
.
sorted_by
)
guarder
=
Node
(
key
=
''
,
value
=
'Guarder'
)
guarder
=
Node
(
key
=
''
,
value
=
'Guarder'
)
guarder
.
_assets
=
[]
guarder
.
_assets
=
[]
...
@@ -119,11 +121,11 @@ class NodeUtil:
...
@@ -119,11 +121,11 @@ class NodeUtil:
def
get_nodes_by_queryset
(
self
,
queryset
):
def
get_nodes_by_queryset
(
self
,
queryset
):
nodes
=
[]
nodes
=
[]
for
n
in
queryset
:
for
n
in
queryset
:
node
=
self
.
_nodes
.
get
(
n
.
key
)
node
=
self
.
get_node_by_key
(
n
.
key
)
if
not
node
:
if
not
node
:
continue
continue
nodes
.
append
(
node
s
)
nodes
.
append
(
node
)
return
[
self
]
return
nodes
def
get_node_by_key
(
self
,
key
):
def
get_node_by_key
(
self
,
key
):
return
self
.
_nodes
.
get
(
key
)
return
self
.
_nodes
.
get
(
key
)
...
@@ -156,11 +158,17 @@ class NodeUtil:
...
@@ -156,11 +158,17 @@ class NodeUtil:
tree_nodes
.
add
(
node
)
tree_nodes
.
add
(
node
)
if
with_children
:
if
with_children
:
tree_nodes
.
update
(
node
.
_children
)
tree_nodes
.
update
(
node
.
_children
)
for
n
in
tree_nodes
:
delattr
(
n
,
'_children'
)
delattr
(
n
,
'_parents'
)
return
list
(
tree_nodes
)
return
list
(
tree_nodes
)
def
get_nodes_parents
(
self
,
nodes
,
with_self
=
True
):
parents
=
set
()
for
n
in
nodes
:
node
=
self
.
get_node_by_key
(
n
.
key
)
parents
.
update
(
set
(
node
.
_parents
))
if
with_self
:
parents
.
add
(
node
)
return
parents
def
test_node_tree
():
def
test_node_tree
():
tree
=
NodeUtil
()
tree
=
NodeUtil
()
...
...
apps/perms/api/asset_permission.py
View file @
ae690050
...
@@ -35,7 +35,8 @@ class AssetPermissionViewSet(viewsets.ModelViewSet):
...
@@ -35,7 +35,8 @@ class AssetPermissionViewSet(viewsets.ModelViewSet):
permission_classes
=
(
IsOrgAdmin
,)
permission_classes
=
(
IsOrgAdmin
,)
def
get_serializer_class
(
self
):
def
get_serializer_class
(
self
):
if
self
.
action
in
(
"list"
,
'retrieve'
):
if
self
.
action
in
(
"list"
,
'retrieve'
)
and
\
self
.
request
.
query_params
.
get
(
"display"
):
return
serializers
.
AssetPermissionListSerializer
return
serializers
.
AssetPermissionListSerializer
return
self
.
serializer_class
return
self
.
serializer_class
...
...
apps/perms/api/user_permission.py
View file @
ae690050
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
#
#
import
time
from
hashlib
import
md5
from
hashlib
import
md5
from
django.core.cache
import
cache
from
django.core.cache
import
cache
from
django.conf
import
settings
from
django.conf
import
settings
...
@@ -261,14 +261,19 @@ class UserGrantedNodesWithAssetsAsTreeApi(UserPermissionCacheMixin, ListAPIView)
...
@@ -261,14 +261,19 @@ class UserGrantedNodesWithAssetsAsTreeApi(UserPermissionCacheMixin, ListAPIView)
nodes
=
util
.
get_nodes_with_assets
()
nodes
=
util
.
get_nodes_with_assets
()
print
(
"22222222222222"
)
print
(
"22222222222222"
)
for
node
,
assets
in
nodes
.
items
():
for
node
,
assets
in
nodes
.
items
():
now
=
time
.
time
()
print
(
"Parse to node"
)
data
=
parse_node_to_tree_node
(
node
)
data
=
parse_node_to_tree_node
(
node
)
print
(
"parse to node end, using: {0:.2f}"
.
format
(
time
.
time
()
-
now
))
queryset
.
append
(
data
)
queryset
.
append
(
data
)
if
not
self
.
show_assets
:
if
not
self
.
show_assets
:
continue
continue
for
asset
,
system_users
in
assets
.
items
():
for
asset
,
system_users
in
assets
.
items
():
now1
=
time
.
time
()
print
(
"parse to asset"
)
data
=
parse_asset_to_tree_node
(
node
,
asset
,
system_users
)
data
=
parse_asset_to_tree_node
(
node
,
asset
,
system_users
)
print
(
"parse to asset end, using: {0:.2f}"
.
format
(
time
.
time
()
-
now1
))
queryset
.
append
(
data
)
queryset
.
append
(
data
)
queryset
=
sorted
(
queryset
)
return
queryset
return
queryset
...
...
apps/perms/forms/asset_permission.py
View file @
ae690050
...
@@ -74,13 +74,13 @@ class AssetPermissionForm(OrgModelForm):
...
@@ -74,13 +74,13 @@ class AssetPermissionForm(OrgModelForm):
'system_users'
:
forms
.
SelectMultiple
(
'system_users'
:
forms
.
SelectMultiple
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'System user'
)}
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'System user'
)}
),
),
'action'
:
forms
.
CheckboxSelectMultiple
()
'action
s
'
:
forms
.
CheckboxSelectMultiple
()
}
}
labels
=
{
labels
=
{
'nodes'
:
_
(
"Node"
),
'nodes'
:
_
(
"Node"
),
}
}
help_texts
=
{
help_texts
=
{
'action'
:
_
(
'Tips: The RDP protocol does not support separate '
'action
s
'
:
_
(
'Tips: The RDP protocol does not support separate '
'controls for uploading or downloading files'
)
'controls for uploading or downloading files'
)
}
}
...
...
apps/perms/migrations/0006_auto_20190628_1921.py
View file @
ae690050
...
@@ -36,7 +36,7 @@ class Migration(migrations.Migration):
...
@@ -36,7 +36,7 @@ class Migration(migrations.Migration):
migrations
.
AddField
(
migrations
.
AddField
(
model_name
=
'assetpermission'
,
model_name
=
'assetpermission'
,
name
=
'action'
,
name
=
'action'
,
field
=
models
.
IntegerField
(
choices
=
[(
255
,
'All'
),
(
1
,
'Connect'
),
(
2
,
'Upload file'
),
(
5
,
'Upload download'
),
(
4
,
'Download file'
)],
default
=
255
,
verbose_name
=
'Action
'
),
field
=
models
.
IntegerField
(
choices
=
[(
255
,
'All'
),
(
1
,
'Connect'
),
(
2
,
'Upload file'
),
(
4
,
'Download file'
),
(
6
,
'Upload download'
)],
default
=
255
,
verbose_name
=
'Actions
'
),
),
),
migrations
.
RunPython
(
migrate_old_actions
),
migrations
.
RunPython
(
migrate_old_actions
),
]
]
apps/perms/migrations/0007_remove_assetpermission_actions.py
View file @
ae690050
...
@@ -14,4 +14,9 @@ class Migration(migrations.Migration):
...
@@ -14,4 +14,9 @@ class Migration(migrations.Migration):
model_name
=
'assetpermission'
,
model_name
=
'assetpermission'
,
name
=
'actions'
,
name
=
'actions'
,
),
),
migrations
.
RenameField
(
model_name
=
'assetpermission'
,
old_name
=
'action'
,
new_name
=
'actions'
,
),
]
]
apps/perms/models/asset_permission.py
View file @
ae690050
...
@@ -39,39 +39,46 @@ class ActionFlag:
...
@@ -39,39 +39,46 @@ class ActionFlag:
UPLOAD
=
0
b00000010
UPLOAD
=
0
b00000010
DOWNLOAD
=
0
b00000100
DOWNLOAD
=
0
b00000100
UPDOWNLOAD
=
UPLOAD
|
DOWNLOAD
UPDOWNLOAD
=
UPLOAD
|
DOWNLOAD
CONNECT_UPLOADOWN
=
CONNECT
|
UPDOWNLOAD
ALL
=
0
b11111111
ALL
=
0
b11111111
NAME_MAP
=
{
"connect"
:
CONNECT
,
"upload"
:
UPLOAD
,
"download"
:
DOWNLOAD
,
"updownload"
:
UPDOWNLOAD
,
"all"
:
ALL
,
}
CHOICES
=
(
DB_
CHOICES
=
(
(
ALL
,
_
(
'All'
)),
(
ALL
,
_
(
'All'
)),
(
CONNECT
,
_
(
'Connect'
)),
(
CONNECT
,
_
(
'Connect'
)),
(
UPDOWNLOAD
,
_
(
"Upload download"
)),
(
UPLOAD
,
_
(
'Upload file'
)),
(
UPLOAD
,
_
(
'Upload file'
)),
(
DOWNLOAD
,
_
(
'Download file'
)),
(
DOWNLOAD
,
_
(
'Download file'
)),
(
UPDOWNLOAD
,
_
(
"Upload download"
)),
)
)
NAME_MAP
=
{
ALL
:
"all"
,
CONNECT
:
"connect"
,
UPLOAD
:
"upload_file"
,
DOWNLOAD
:
"download_file"
,
UPDOWNLOAD
:
"updownload"
,
}
NAME_MAP_REVERSE
=
dict
({
v
:
k
for
k
,
v
in
NAME_MAP
.
items
()})
CHOICES
=
[]
for
i
,
j
in
DB_CHOICES
:
CHOICES
.
append
((
NAME_MAP
[
i
],
j
))
@classmethod
@classmethod
def
value_to_choices
(
cls
,
value
):
def
value_to_choices
(
cls
,
value
):
value
=
int
(
value
)
value
=
int
(
value
)
if
value
==
cls
.
ALL
:
choices
=
[
cls
.
NAME_MAP
[
i
]
for
i
,
j
in
cls
.
DB_CHOICES
if
value
&
i
==
i
]
return
[
cls
.
ALL
]
return
choices
elif
value
==
cls
.
UPDOWNLOAD
:
return
[
cls
.
UPDOWNLOAD
]
elif
value
==
cls
.
CONNECT_UPLOADOWN
:
return
[
cls
.
CONNECT
,
cls
.
UPDOWNLOAD
]
else
:
return
[
i
for
i
in
dict
(
cls
.
CHOICES
)
if
i
==
i
&
int
(
value
)]
@classmethod
@classmethod
def
choices_to_value
(
cls
,
value
):
def
choices_to_value
(
cls
,
value
):
return
reduce
(
lambda
x
,
y
:
int
(
x
)
|
int
(
y
),
value
)
def
to_choices
(
x
,
y
):
x
=
cls
.
NAME_MAP_REVERSE
.
get
(
x
,
0
)
y
=
cls
.
NAME_MAP_REVERSE
.
get
(
y
,
0
)
return
x
|
y
return
reduce
(
to_choices
,
value
)
@classmethod
def
choices
(
cls
):
return
[(
cls
.
NAME_MAP
[
i
],
j
)
for
i
,
j
in
cls
.
DB_CHOICES
]
class
AssetPermission
(
BasePermission
):
class
AssetPermission
(
BasePermission
):
...
@@ -79,7 +86,7 @@ class AssetPermission(BasePermission):
...
@@ -79,7 +86,7 @@ class AssetPermission(BasePermission):
nodes
=
models
.
ManyToManyField
(
'assets.Node'
,
related_name
=
'granted_by_permissions'
,
blank
=
True
,
verbose_name
=
_
(
"Nodes"
))
nodes
=
models
.
ManyToManyField
(
'assets.Node'
,
related_name
=
'granted_by_permissions'
,
blank
=
True
,
verbose_name
=
_
(
"Nodes"
))
system_users
=
models
.
ManyToManyField
(
'assets.SystemUser'
,
related_name
=
'granted_by_permissions'
,
verbose_name
=
_
(
"System user"
))
system_users
=
models
.
ManyToManyField
(
'assets.SystemUser'
,
related_name
=
'granted_by_permissions'
,
verbose_name
=
_
(
"System user"
))
# actions = models.ManyToManyField(Action, related_name='permissions', blank=True, verbose_name=_('Action'))
# actions = models.ManyToManyField(Action, related_name='permissions', blank=True, verbose_name=_('Action'))
action
=
models
.
IntegerField
(
choices
=
ActionFlag
.
CHOICES
,
default
=
ActionFlag
.
ALL
,
verbose_name
=
_
(
"Action
"
))
action
s
=
models
.
IntegerField
(
choices
=
ActionFlag
.
DB_CHOICES
,
default
=
ActionFlag
.
ALL
,
verbose_name
=
_
(
"Actions
"
))
class
Meta
:
class
Meta
:
unique_together
=
[(
'org_id'
,
'name'
)]
unique_together
=
[(
'org_id'
,
'name'
)]
...
...
apps/perms/serializers/asset_permission.py
View file @
ae690050
...
@@ -38,7 +38,7 @@ class ActionDisplayField(ActionField):
...
@@ -38,7 +38,7 @@ class ActionDisplayField(ActionField):
class
AssetPermissionCreateUpdateSerializer
(
BulkOrgResourceModelSerializer
):
class
AssetPermissionCreateUpdateSerializer
(
BulkOrgResourceModelSerializer
):
action
=
ActionField
()
action
s
=
ActionField
()
class
Meta
:
class
Meta
:
model
=
AssetPermission
model
=
AssetPermission
...
@@ -51,7 +51,7 @@ class AssetPermissionListSerializer(BulkOrgResourceModelSerializer):
...
@@ -51,7 +51,7 @@ class AssetPermissionListSerializer(BulkOrgResourceModelSerializer):
assets
=
StringManyToManyField
(
many
=
True
,
read_only
=
True
)
assets
=
StringManyToManyField
(
many
=
True
,
read_only
=
True
)
nodes
=
StringManyToManyField
(
many
=
True
,
read_only
=
True
)
nodes
=
StringManyToManyField
(
many
=
True
,
read_only
=
True
)
system_users
=
StringManyToManyField
(
many
=
True
,
read_only
=
True
)
system_users
=
StringManyToManyField
(
many
=
True
,
read_only
=
True
)
action
=
ActionDisplayField
()
action
s
=
ActionDisplayField
()
is_valid
=
serializers
.
BooleanField
()
is_valid
=
serializers
.
BooleanField
()
is_expired
=
serializers
.
BooleanField
()
is_expired
=
serializers
.
BooleanField
()
...
...
apps/perms/templates/perms/asset_permission_list.html
View file @
ae690050
...
@@ -122,8 +122,8 @@ function format(d) {
...
@@ -122,8 +122,8 @@ function format(d) {
if
(
d
.
system_users
.
length
>
0
)
{
if
(
d
.
system_users
.
length
>
0
)
{
data
+=
makeLabel
([
"{% trans 'System user' %}"
,
d
.
system_users
.
join
(
", "
)])
data
+=
makeLabel
([
"{% trans 'System user' %}"
,
d
.
system_users
.
join
(
", "
)])
}
}
if
(
d
.
action
.
length
>
0
)
{
if
(
d
.
action
s
.
length
>
0
)
{
data
+=
makeLabel
([
"{% trans 'Action' %}"
,
d
.
action
.
join
(
", "
)])
data
+=
makeLabel
([
"{% trans 'Action' %}"
,
d
.
action
s
.
join
(
", "
)])
}
}
return
data
return
data
}
}
...
@@ -180,7 +180,7 @@ function initTable() {
...
@@ -180,7 +180,7 @@ function initTable() {
$
(
td
).
html
(
update_btn
+
del_btn
);
$
(
td
).
html
(
update_btn
+
del_btn
);
}}
}}
],
],
ajax_url
:
'{% url "api-perms:asset-permission-list" %}'
,
ajax_url
:
'{% url "api-perms:asset-permission-list" %}
?display=1
'
,
columns
:
[
columns
:
[
{
data
:
"id"
},
{
data
:
"name"
},
{
data
:
"users"
},
{
data
:
"id"
},
{
data
:
"name"
},
{
data
:
"users"
},
{
data
:
"user_groups"
},
{
data
:
"assets"
},
{
data
:
"user_groups"
},
{
data
:
"assets"
},
...
...
apps/perms/utils/asset_permission.py
View file @
ae690050
...
@@ -17,8 +17,8 @@ from orgs.utils import set_to_root_org
...
@@ -17,8 +17,8 @@ from orgs.utils import set_to_root_org
from
common.utils
import
get_logger
from
common.utils
import
get_logger
from
common.tree
import
TreeNode
from
common.tree
import
TreeNode
from
..
import
const
from
..
import
const
from
..models
import
AssetPermission
,
Action
from
..models
import
AssetPermission
,
Action
,
ActionFlag
from
..hands
import
Node
from
..hands
import
Node
,
Asset
from
assets.utils
import
NodeUtil
from
assets.utils
import
NodeUtil
logger
=
get_logger
(
__file__
)
logger
=
get_logger
(
__file__
)
...
@@ -31,17 +31,57 @@ __all__ = [
...
@@ -31,17 +31,57 @@ __all__ = [
]
]
class
TreeNodeCounter
(
NodeUtil
):
def
__init__
(
self
,
nodes
):
self
.
__nodes
=
nodes
super
()
.
__init__
(
with_assets_amount
=
True
)
def
get_queryset
(
self
):
return
self
.
__nodes
def
timeit
(
func
):
def
wrapper
(
*
args
,
**
kwargs
):
logger
.
debug
(
"Start call: {}"
.
format
(
func
.
__name__
))
now
=
time
.
time
()
result
=
func
(
*
args
,
**
kwargs
)
using
=
time
.
time
()
-
now
logger
.
debug
(
"Call {} end, using: {:.2}s"
.
format
(
func
.
__name__
,
using
))
return
result
return
wrapper
class
GenerateTree
:
class
GenerateTree
:
def
__init__
(
self
):
def
__init__
(
self
):
"""
"""
nodes: {"node_instance": {
nodes = {
"asset_instance": set("system_user")
"<node1>": {
"system_users": {
"system_user": action,
"system_user2": action,
},
"assets": set([<asset_instance>]),
}
}
assets = {
"<asset_instance2>": {
"system_user": action,
"system_user2": action,
},
}
}
"""
"""
self
.
node_util
=
NodeUtil
()
self
.
_node_util
=
None
self
.
nodes
=
defaultdict
(
dict
)
self
.
nodes
=
defaultdict
(
lambda
:
{
"system_users"
:
defaultdict
(
int
),
"assets"
:
set
(),
"assets_amount"
:
0
})
self
.
assets
=
defaultdict
(
lambda
:
defaultdict
(
int
))
self
.
_root_node
=
None
self
.
_root_node
=
None
self
.
_ungroup_node
=
None
self
.
_ungroup_node
=
None
self
.
_nodes_with_assets
=
None
@property
def
node_util
(
self
):
if
not
self
.
_node_util
:
self
.
_node_util
=
NodeUtil
()
return
self
.
_node_util
@property
@property
def
root_node
(
self
):
def
root_node
(
self
):
...
@@ -66,35 +106,79 @@ class GenerateTree:
...
@@ -66,35 +106,79 @@ class GenerateTree:
node_key
=
'0:0'
node_key
=
'0:0'
node_value
=
_
(
"Default"
)
node_value
=
_
(
"Default"
)
node
=
Node
(
id
=
node_id
,
key
=
node_key
,
value
=
node_value
)
node
=
Node
(
id
=
node_id
,
key
=
node_key
,
value
=
node_value
)
self
.
add_node
(
node
)
self
.
add_node
(
node
,
{}
)
self
.
_ungroup_node
=
node
self
.
_ungroup_node
=
node
return
node
return
node
def
add_asset
(
self
,
asset
,
system_users
):
@timeit
def
add_assets_without_system_users
(
self
,
assets
):
for
asset
in
assets
:
self
.
add_asset
(
asset
,
{})
@timeit
def
add_assets
(
self
,
assets
):
for
asset
,
system_users
in
assets
.
items
():
self
.
add_asset
(
asset
,
system_users
)
@timeit
def
add_asset
(
self
,
asset
,
system_users
=
None
):
nodes
=
asset
.
nodes
.
all
()
nodes
=
asset
.
nodes
.
all
()
for
node
in
nodes
:
nodes
=
self
.
node_util
.
get_nodes_by_queryset
(
nodes
)
if
node
in
self
.
nodes
:
if
not
system_users
:
self
.
nodes
[
node
][
asset
]
.
update
(
system_users
)
system_users
=
defaultdict
(
int
)
else
:
else
:
self
.
nodes
[
self
.
ungrouped_node
][
asset
]
.
update
(
system_users
)
system_users
=
{
k
:
v
for
k
,
v
in
system_users
.
items
()}
_system_users
=
self
.
assets
[
asset
]
def
get_nodes
(
self
):
for
system_user
,
action
in
_system_users
.
items
():
for
node
in
self
.
nodes
:
system_users
[
system_user
]
|=
action
assets
=
set
(
self
.
nodes
.
get
(
node
)
.
keys
())
for
n
in
self
.
nodes
.
keys
():
# 获取父节点们
if
n
.
key
.
startswith
(
node
.
key
+
':'
):
parents
=
self
.
node_util
.
get_nodes_parents
(
nodes
,
with_self
=
True
)
assets
.
update
(
set
(
self
.
nodes
[
n
]
.
keys
()))
for
node
in
parents
:
node
.
assets_amount
=
len
(
assets
)
_system_users
=
self
.
nodes
[
node
][
"system_users"
]
return
self
.
nodes
self
.
nodes
[
node
][
"assets_amount"
]
+=
1
for
system_user
,
action
in
_system_users
.
items
():
def
add_node
(
self
,
node
):
system_users
[
system_user
]
|=
action
self
.
nodes
[
node
]
=
defaultdict
(
set
)
# 过滤系统用户的协议
system_users
=
{
s
:
v
for
s
,
v
in
system_users
.
items
()
if
asset
.
has_protocol
(
s
.
protocol
)}
self
.
assets
[
asset
]
=
system_users
in_nodes
=
set
(
self
.
nodes
.
keys
())
&
set
(
nodes
)
if
not
in_nodes
:
self
.
nodes
[
self
.
ungrouped_node
][
"assets_amount"
]
+=
1
self
.
nodes
[
self
.
ungrouped_node
][
"assets"
]
.
add
(
system_users
)
return
for
node
in
in_nodes
:
self
.
nodes
[
node
][
"assets"
]
.
add
(
asset
)
def
add_node
(
self
,
node
,
system_users
=
None
):
if
not
system_users
:
system_users
=
defaultdict
(
int
)
self
.
nodes
[
node
][
"system_users"
]
=
system_users
# 添加树节点
# 添加树节点
@timeit
def
add_nodes
(
self
,
nodes
):
def
add_nodes
(
self
,
nodes
):
need_nodes
=
self
.
node_util
.
get_family
(
nodes
,
with_children
=
True
)
_nodes
=
nodes
.
keys
()
for
node
in
need_nodes
:
family
=
self
.
node_util
.
get_family
(
_nodes
,
with_children
=
True
)
self
.
add_node
(
node
)
for
node
in
family
:
self
.
add_node
(
node
,
nodes
.
get
(
node
,
{}))
def
get_assets
(
self
):
return
dict
(
self
.
assets
)
@timeit
def
get_nodes_with_assets
(
self
):
if
self
.
_nodes_with_assets
:
return
self
.
_nodes_with_assets
nodes
=
{}
for
node
,
values
in
self
.
nodes
.
items
():
node
.
_assets_amount
=
values
[
"assets_amount"
]
nodes
[
node
]
=
{
asset
:
self
.
assets
.
get
(
asset
,
{})
for
asset
in
values
[
"assets"
]}
self
.
_nodes_with_assets
=
nodes
return
dict
(
nodes
)
def
get_user_permissions
(
user
,
include_group
=
True
):
def
get_user_permissions
(
user
,
include_group
=
True
):
...
@@ -131,17 +215,6 @@ def get_system_user_permissions(system_user):
...
@@ -131,17 +215,6 @@ def get_system_user_permissions(system_user):
)
)
def
timeit
(
func
):
def
wrapper
(
*
args
,
**
kwargs
):
logger
.
debug
(
"Start call: {}"
.
format
(
func
.
__name__
))
now
=
time
.
time
()
result
=
func
(
*
args
,
**
kwargs
)
using
=
time
.
time
()
-
now
logger
.
debug
(
"Call {} end, using: {:.2}"
.
format
(
func
.
__name__
,
using
))
return
result
return
wrapper
class
AssetPermissionCacheMixin
:
class
AssetPermissionCacheMixin
:
CACHE_KEY_PREFIX
=
'_ASSET_PERM_CACHE_'
CACHE_KEY_PREFIX
=
'_ASSET_PERM_CACHE_'
CACHE_META_KEY_PREFIX
=
'_ASSET_PERM_META_KEY_'
CACHE_META_KEY_PREFIX
=
'_ASSET_PERM_META_KEY_'
...
@@ -216,6 +289,16 @@ class AssetPermissionCacheMixin:
...
@@ -216,6 +289,16 @@ class AssetPermissionCacheMixin:
cached
=
cache
.
get
(
self
.
system_key
)
cached
=
cache
.
get
(
self
.
system_key
)
return
cached
return
cached
def
get_assets
(
self
):
if
self
.
_is_not_using_cache
():
return
self
.
get_assets_from_cache
()
elif
self
.
_is_refresh_cache
():
self
.
expire_cache
()
return
self
.
get_assets_from_cache
()
else
:
self
.
expire_cache
()
return
self
.
get_assets_without_cache
()
def
get_system_users
(
self
):
def
get_system_users
(
self
):
if
self
.
_is_using_cache
():
if
self
.
_is_using_cache
():
return
self
.
get_system_user_from_cache
()
return
self
.
get_system_user_from_cache
()
...
@@ -282,57 +365,6 @@ class AssetPermissionCacheMixin:
...
@@ -282,57 +365,6 @@ class AssetPermissionCacheMixin:
cache
.
delete_pattern
(
key
)
cache
.
delete_pattern
(
key
)
class
FlatPermissionQueryset
(
set
):
def
add_many
(
self
,
assets_or_nodes
,
system_users
,
action
,
rtp
=
"asset"
):
print
(
"Add many: {}-{}-{}"
.
format
(
len
(
assets_or_nodes
),
len
(
system_users
),
action
))
if
not
any
([
assets_or_nodes
,
system_users
,
action
]):
return
iterable
=
itertools
.
product
(
assets_or_nodes
,
system_users
,
[
action
])
for
source
,
sysuser
,
action
in
iterable
:
permission
=
FlatPermission
(
source
,
sysuser
,
action
,
rtp
=
rtp
)
print
(
"ADDDDDDDDDDDDDDDd"
)
self
.
add
(
permission
)
def
group_by_resource
(
self
):
resources
=
defaultdict
(
lambda
:
defaultdict
(
int
))
for
i
in
self
:
resources
[
i
.
resource
][
i
.
system_user
]
|=
i
.
action
return
resources
class
FlatPermission
:
def
__init__
(
self
,
assets_or_node
,
system_user
,
action
,
rtp
=
"asset"
):
self
.
id
=
"{}_{}_{}"
.
format
(
assets_or_node
.
id
,
system_user
.
id
,
action
)
self
.
resource
=
assets_or_node
self
.
resource_type
=
rtp
self
.
system_user
=
system_user
self
.
action
=
action
def
__eq__
(
self
,
other
):
if
self
.
id
==
other
.
id
:
return
True
# 资产不同
if
self
.
resource_type
==
"asset"
and
self
.
id
!=
other
.
id
:
return
False
# 不是子节点
elif
self
.
resource_type
==
"node"
and
not
other
.
resource
.
key
.
startswith
(
self
.
resource
.
key
):
return
False
# 系统用户优先级大于后者,则相同
if
self
.
system_user
.
priority
>
self
.
system_user
.
priority
:
return
True
# 如果系统用户不同,则不同
elif
self
.
system_user
!=
other
.
system_user
:
return
False
# 如果action为与后的结果则相同
if
self
.
action
==
self
.
action
|
other
.
action
:
return
True
return
False
def
__hash__
(
self
):
return
hash
(
self
.
id
)
class
AssetPermissionUtil
(
AssetPermissionCacheMixin
):
class
AssetPermissionUtil
(
AssetPermissionCacheMixin
):
get_permissions_map
=
{
get_permissions_map
=
{
"User"
:
get_user_permissions
,
"User"
:
get_user_permissions
,
...
@@ -353,6 +385,7 @@ class AssetPermissionUtil(AssetPermissionCacheMixin):
...
@@ -353,6 +385,7 @@ class AssetPermissionUtil(AssetPermissionCacheMixin):
self
.
tree
=
GenerateTree
()
self
.
tree
=
GenerateTree
()
self
.
change_org_if_need
()
self
.
change_org_if_need
()
self
.
nodes
=
None
self
.
nodes
=
None
self
.
_nodes
=
None
@staticmethod
@staticmethod
def
change_org_if_need
():
def
change_org_if_need
():
...
@@ -380,29 +413,32 @@ class AssetPermissionUtil(AssetPermissionCacheMixin):
...
@@ -380,29 +413,32 @@ class AssetPermissionUtil(AssetPermissionCacheMixin):
返回用户/组授权规则直接关联的节点
返回用户/组授权规则直接关联的节点
:return: {node1: {system_user1: {'actions': set()},}}
:return: {node1: {system_user1: {'actions': set()},}}
"""
"""
queryset
=
FlatPermissionQueryset
(
)
nodes
=
defaultdict
(
lambda
:
defaultdict
(
int
)
)
for
perm
in
self
.
permissions
:
for
perm
in
self
.
permissions
:
actions
=
perm
.
action
actions
=
[
perm
.
actions
]
system_users
=
perm
.
system_users
.
all
()
system_users
=
perm
.
system_users
.
all
()
nodes
=
perm
.
nodes
.
all
()
_nodes
=
perm
.
nodes
.
all
()
queryset
.
add_many
(
nodes
,
system_users
,
actions
,
rtp
=
"nodes"
)
for
node
,
system_user
,
action
in
itertools
.
product
(
_nodes
,
system_users
,
actions
):
print
(
queryset
)
nodes
[
node
][
system_user
]
|=
action
return
queryset
.
group_by_resource
()
self
.
tree
.
add_nodes
(
nodes
)
return
nodes
@timeit
@timeit
def
get_assets_direct
(
self
):
def
get_assets_direct
(
self
):
"""
"""
返回用户授权规则直接关联的资产
返回用户授权规则直接关联的资产
:return: {asset1: {system_user1:
{'actions': set()}
,}}
:return: {asset1: {system_user1:
1
,}}
"""
"""
queryset
=
FlatPermissionQueryset
(
)
assets
=
defaultdict
(
lambda
:
defaultdict
(
int
)
)
for
perm
in
self
.
permissions
:
for
perm
in
self
.
permissions
:
action
=
perm
.
action
action
s
=
[
perm
.
actions
]
assets
=
perm
.
assets
.
all
(
)
_assets
=
perm
.
assets
.
all
()
.
prefetch_related
(
'nodes'
,
'protocols'
)
system_users
=
perm
.
system_users
.
all
()
system_users
=
perm
.
system_users
.
all
()
queryset
.
add_many
(
assets
,
system_users
,
action
,
rtp
=
"assets"
)
iterable
=
itertools
.
product
(
_assets
,
system_users
,
actions
)
print
(
queryset
)
for
asset
,
system_user
,
action
in
iterable
:
return
queryset
.
group_by_resource
()
assets
[
asset
][
system_user
]
|=
action
self
.
tree
.
add_assets
(
assets
)
return
assets
@timeit
@timeit
def
get_assets_without_cache
(
self
):
def
get_assets_without_cache
(
self
):
...
@@ -411,24 +447,34 @@ class AssetPermissionUtil(AssetPermissionCacheMixin):
...
@@ -411,24 +447,34 @@ class AssetPermissionUtil(AssetPermissionCacheMixin):
"""
"""
if
self
.
_assets
:
if
self
.
_assets
:
return
self
.
_assets
return
self
.
_assets
assets
=
self
.
get_assets_direct
()
nodes
=
self
.
get_nodes_direct
()
nodes
=
self
.
get_nodes_direct
()
print
(
"++++++++++++++++++++++"
)
pattern
=
set
()
print
(
assets
)
for
node
in
nodes
:
print
(
"---------------------"
)
pattern
.
add
(
r'^{0}$|^{0}:'
.
format
(
node
.
key
))
print
(
nodes
)
pattern
=
'|'
.
join
(
list
(
pattern
))
now
=
time
.
time
()
print
(
"Get node assets start"
)
if
pattern
:
assets
=
Asset
.
objects
.
filter
(
nodes__key__regex
=
pattern
)
\
.
prefetch_related
(
'nodes'
,
"protocols"
)
.
only
(
'id'
,
'hostname'
,
'ip'
)
.
distinct
()
else
:
assets
=
[]
assets
=
list
(
assets
)
print
(
"Get node assets end, using: {}"
.
format
(
time
.
time
()
-
now
))
self
.
tree
.
add_assets_without_system_users
(
assets
)
assets
=
self
.
tree
.
get_assets
()
self
.
_assets
=
assets
return
assets
@timeit
@timeit
def
get_nodes_with_assets_without_cache
(
self
):
def
get_nodes_with_assets_without_cache
(
self
):
"""
"""
返回节点并且包含资产
返回节点并且包含资产
{"node": {"asset
s": set("system_user"
)}}
{"node": {"asset
": {"system_user": 1}
)}}
:return:
:return:
"""
"""
assets
=
self
.
get_assets_without_cache
()
self
.
get_assets_without_cache
()
for
asset
,
system_users
in
assets
.
items
():
return
self
.
tree
.
get_nodes_with_assets
()
self
.
tree
.
add_asset
(
asset
,
system_users
)
return
self
.
tree
.
get_nodes
()
def
get_system_user_without_cache
(
self
):
def
get_system_user_without_cache
(
self
):
system_users
=
set
()
system_users
=
set
()
...
@@ -460,9 +506,7 @@ def sort_assets(assets, order_by='hostname', reverse=False):
...
@@ -460,9 +506,7 @@ def sort_assets(assets, order_by='hostname', reverse=False):
def
parse_node_to_tree_node
(
node
):
def
parse_node_to_tree_node
(
node
):
from
..
import
serializers
name
=
'{} ({})'
.
format
(
node
.
value
,
node
.
assets_amount
)
name
=
'{} ({})'
.
format
(
node
.
value
,
node
.
assets_amount
)
node_serializer
=
serializers
.
GrantedNodeSerializer
(
node
)
data
=
{
data
=
{
'id'
:
node
.
key
,
'id'
:
node
.
key
,
'name'
:
name
,
'name'
:
name
,
...
@@ -471,7 +515,11 @@ def parse_node_to_tree_node(node):
...
@@ -471,7 +515,11 @@ def parse_node_to_tree_node(node):
'isParent'
:
True
,
'isParent'
:
True
,
'open'
:
node
.
is_root
(),
'open'
:
node
.
is_root
(),
'meta'
:
{
'meta'
:
{
'node'
:
node_serializer
.
data
,
'node'
:
{
"id"
:
node
.
id
,
"key"
:
node
.
key
,
"value"
:
node
.
value
,
},
'type'
:
'node'
'type'
:
'node'
}
}
}
}
...
@@ -480,23 +528,21 @@ def parse_node_to_tree_node(node):
...
@@ -480,23 +528,21 @@ def parse_node_to_tree_node(node):
def
parse_asset_to_tree_node
(
node
,
asset
,
system_users
):
def
parse_asset_to_tree_node
(
node
,
asset
,
system_users
):
system_users_protocol_matched
=
[
s
for
s
in
system_users
if
asset
.
has_protocol
(
s
.
protocol
)]
icon_skin
=
'file'
icon_skin
=
'file'
if
asset
.
platform
.
lower
()
==
'windows'
:
if
asset
.
platform
.
lower
()
==
'windows'
:
icon_skin
=
'windows'
icon_skin
=
'windows'
elif
asset
.
platform
.
lower
()
==
'linux'
:
elif
asset
.
platform
.
lower
()
==
'linux'
:
icon_skin
=
'linux'
icon_skin
=
'linux'
system_users
=
[]
_
system_users
=
[]
for
system_user
in
system_users_protocol_matched
:
for
system_user
,
action
in
system_users
.
items
()
:
system_users
.
append
({
_
system_users
.
append
({
'id'
:
system_user
.
id
,
'id'
:
system_user
.
id
,
'name'
:
system_user
.
name
,
'name'
:
system_user
.
name
,
'username'
:
system_user
.
username
,
'username'
:
system_user
.
username
,
'protocol'
:
system_user
.
protocol
,
'protocol'
:
system_user
.
protocol
,
'priority'
:
system_user
.
priority
,
'priority'
:
system_user
.
priority
,
'login_mode'
:
system_user
.
login_mode
,
'login_mode'
:
system_user
.
login_mode
,
'actions'
:
[
action
.
name
for
action
in
system_user
.
actions
],
'actions'
:
[
ActionFlag
.
value_to_choices
(
action
)],
'comment'
:
system_user
.
comment
,
})
})
data
=
{
data
=
{
'id'
:
str
(
asset
.
id
),
'id'
:
str
(
asset
.
id
),
...
@@ -507,7 +553,7 @@ def parse_asset_to_tree_node(node, asset, system_users):
...
@@ -507,7 +553,7 @@ def parse_asset_to_tree_node(node, asset, system_users):
'open'
:
False
,
'open'
:
False
,
'iconSkin'
:
icon_skin
,
'iconSkin'
:
icon_skin
,
'meta'
:
{
'meta'
:
{
'system_users'
:
system_users
,
'system_users'
:
_
system_users
,
'type'
:
'asset'
,
'type'
:
'asset'
,
'asset'
:
{
'asset'
:
{
'id'
:
asset
.
id
,
'id'
:
asset
.
id
,
...
...
apps/perms/utils/test_asset_permission.py
deleted
100644 → 0
View file @
8f699fa3
# -*- coding: utf-8 -*-
#
from
django.test
import
TestCase
from
assets.models
import
Node
,
SystemUser
from
.asset_permission
import
FlatPermission
from
..models
import
ActionFlag
class
TestFlatPermissionEqual
(
TestCase
):
def
setUp
(
self
):
node1
=
Node
(
value
=
"parent"
,
key
=
"1:1"
)
node2
=
Node
(
value
=
"child"
,
key
=
"1:1:1"
)
system_user1
=
SystemUser
(
username
=
"name1"
,
name
=
"name1"
,
priority
=
20
)
system_user2
=
SystemUser
(
username
=
"name2"
,
name
=
"name2"
,
priority
=
10
)
action1
=
ActionFlag
.
ALL
action2
=
ActionFlag
.
CONNECT
action3
=
ActionFlag
.
UPDOWNLOAD
perm1
=
FlatPermission
(
node1
,
system_user1
,
action1
)
perm2
=
FlatPermission
(
node2
,
system_user1
,
action1
)
perm3
=
FlatPermission
(
node2
,
system_user2
,
action1
)
self
.
groups
=
(
(
perm1
,
perm2
,
True
),
(
perm1
,
perm3
,
True
),
)
def
test_equal
(
self
):
for
k
,
k2
,
wanted
in
self
.
groups
:
if
(
k
==
k2
)
!=
wanted
:
print
(
"Not equal {} {}"
,
k
,
k2
)
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