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
fffa0def
Commit
fffa0def
authored
Apr 08, 2018
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Update] 修改api和view
parent
d0ede246
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
211 additions
and
173 deletions
+211
-173
asset.py
apps/assets/forms/asset.py
+11
-5
user.py
apps/assets/models/user.py
+5
-7
system_user.py
apps/assets/serializers/system_user.py
+1
-1
signals_handler.py
apps/assets/signals_handler.py
+28
-15
tasks.py
apps/assets/tasks.py
+7
-42
asset_create.html
apps/assets/templates/assets/asset_create.html
+1
-1
asset_update.html
apps/assets/templates/assets/asset_update.html
+1
-1
api.py
apps/perms/api.py
+60
-37
serializers.py
apps/perms/serializers.py
+4
-25
signals_handler.py
apps/perms/signals_handler.py
+31
-7
asset_permission_list.html
apps/perms/templates/perms/asset_permission_list.html
+10
-1
api_urls.py
apps/perms/urls/api_urls.py
+3
-0
utils.py
apps/perms/utils.py
+23
-3
user_granted_asset.html
apps/users/templates/users/user_granted_asset.html
+14
-15
user_group_granted_asset.html
apps/users/templates/users/user_group_granted_asset.html
+12
-13
No files found.
apps/assets/forms/asset.py
View file @
fffa0def
...
...
@@ -27,13 +27,16 @@ class AssetCreateForm(forms.ModelForm):
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Admin user'
)
}),
'labels'
:
forms
.
SelectMultiple
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Label
s
'
)
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Label'
)
}),
'port'
:
forms
.
TextInput
(),
'domain'
:
forms
.
Select
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Domain'
)
}),
}
labels
=
{
'nodes'
:
_
(
"Node"
),
}
help_texts
=
{
'hostname'
:
'* required'
,
'ip'
:
'* required'
,
...
...
@@ -57,19 +60,22 @@ class AssetUpdateForm(forms.ModelForm):
]
widgets
=
{
'nodes'
:
forms
.
SelectMultiple
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Node
s
'
)
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Node'
)
}),
'admin_user'
:
forms
.
Select
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Admin user'
)
}),
'labels'
:
forms
.
SelectMultiple
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Label
s
'
)
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Label'
)
}),
'port'
:
forms
.
TextInput
(),
'domain'
:
forms
.
Select
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Domain'
)
}),
}
labels
=
{
'nodes'
:
_
(
"Node"
),
}
help_texts
=
{
'hostname'
:
'* required'
,
'ip'
:
'* required'
,
...
...
@@ -116,10 +122,10 @@ class AssetBulkUpdateForm(forms.ModelForm):
]
widgets
=
{
'labels'
:
forms
.
SelectMultiple
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'
Select labels
'
)}
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'
Label
'
)}
),
'nodes'
:
forms
.
SelectMultiple
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'
Select nodes
'
)}
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'
Node
'
)}
),
}
...
...
apps/assets/models/user.py
View file @
fffa0def
...
...
@@ -3,6 +3,7 @@
#
import
logging
import
uuid
from
django.core.cache
import
cache
from
django.db
import
models
...
...
@@ -100,10 +101,11 @@ class SystemUser(AssetUser):
)
nodes
=
models
.
ManyToManyField
(
'assets.Node'
,
blank
=
True
,
verbose_name
=
_
(
"Nodes"
))
assets
=
models
.
ManyToManyField
(
'assets.Asset'
,
blank
=
True
,
verbose_name
=
_
(
"Assets"
))
priority
=
models
.
IntegerField
(
default
=
10
,
verbose_name
=
_
(
"Priority"
))
protocol
=
models
.
CharField
(
max_length
=
16
,
choices
=
PROTOCOL_CHOICES
,
default
=
'ssh'
,
verbose_name
=
_
(
'Protocol'
))
auto_push
=
models
.
BooleanField
(
default
=
True
,
verbose_name
=
_
(
'Auto push'
))
sudo
=
models
.
TextField
(
default
=
'/
sbin/ifconfig
'
,
verbose_name
=
_
(
'Sudo'
))
sudo
=
models
.
TextField
(
default
=
'/
bin/whoami
'
,
verbose_name
=
_
(
'Sudo'
))
shell
=
models
.
CharField
(
max_length
=
64
,
default
=
'/bin/bash'
,
verbose_name
=
_
(
'Shell'
))
def
__str__
(
self
):
...
...
@@ -119,9 +121,8 @@ class SystemUser(AssetUser):
'auto_push'
:
self
.
auto_push
,
}
@property
def
assets
(
self
):
assets
=
set
()
def
get_assets
(
self
):
assets
=
set
(
self
.
assets
.
all
())
for
node
in
self
.
nodes
.
all
():
assets
.
update
(
set
(
node
.
get_all_assets
()))
return
assets
...
...
@@ -168,6 +169,3 @@ class SystemUser(AssetUser):
except
IntegrityError
:
print
(
'Error continue'
)
continue
apps/assets/serializers/system_user.py
View file @
fffa0def
...
...
@@ -34,7 +34,7 @@ class SystemUserSerializer(serializers.ModelSerializer):
@staticmethod
def
get_assets_amount
(
obj
):
return
len
(
obj
.
assets
)
return
len
(
obj
.
get_assets
()
)
class
SystemUserAuthSerializer
(
AuthSerializer
):
...
...
apps/assets/signals_handler.py
View file @
fffa0def
# -*- coding: utf-8 -*-
#
from
collections
import
defaultdict
from
django.db.models.signals
import
post_save
,
m2m_changed
from
django.dispatch
import
receiver
from
common.utils
import
get_logger
from
.models
import
Asset
,
SystemUser
,
Node
from
.tasks
import
update_assets_hardware_info_util
,
\
test_asset_connectability_util
,
push_system_user_to_node
,
\
push_node_system_users_to_asset
test_asset_connectability_util
,
push_system_user_to_assets
logger
=
get_logger
(
__file__
)
...
...
@@ -31,7 +30,6 @@ def set_asset_root_node(asset):
@receiver
(
post_save
,
sender
=
Asset
,
dispatch_uid
=
"my_unique_identifier"
)
def
on_asset_created_or_update
(
sender
,
instance
=
None
,
created
=
False
,
**
kwargs
):
# set_asset_root_node(instance)
if
created
:
logger
.
info
(
"Asset `{}` create signal received"
.
format
(
instance
))
update_asset_hardware_info_on_created
(
instance
)
...
...
@@ -41,25 +39,39 @@ def on_asset_created_or_update(sender, instance=None, created=False, **kwargs):
@receiver
(
post_save
,
sender
=
SystemUser
,
dispatch_uid
=
"my_unique_identifier"
)
def
on_system_user_update
(
sender
,
instance
=
None
,
created
=
True
,
**
kwargs
):
if
instance
and
not
created
:
for
node
in
instance
.
nodes
.
all
():
push_system_user_to_node
(
instance
,
node
)
logger
.
info
(
"System user `{}` update signal received"
.
format
(
instance
))
assets
=
instance
.
assets
.
all
()
push_system_user_to_assets
.
delay
(
instance
,
assets
)
@receiver
(
m2m_changed
,
sender
=
SystemUser
.
nodes
.
through
)
def
on_system_user_node_change
(
sender
,
instance
=
None
,
**
kwargs
):
def
on_system_user_nodes_change
(
sender
,
instance
=
None
,
**
kwargs
):
if
instance
and
kwargs
[
"action"
]
==
"post_add"
:
assets
=
set
()
nodes
=
kwargs
[
'model'
]
.
objects
.
filter
(
pk__in
=
kwargs
[
'pk_set'
])
for
node
in
nodes
:
assets
.
update
(
set
(
node
.
get_all_assets
()))
instance
.
assets
.
add
(
*
tuple
(
assets
))
@receiver
(
m2m_changed
,
sender
=
SystemUser
.
assets
.
through
)
def
on_system_user_assets_change
(
sender
,
instance
=
None
,
**
kwargs
):
if
instance
and
kwargs
[
"action"
]
==
"post_add"
:
for
pk
in
kwargs
[
'pk_set'
]:
node
=
kwargs
[
'model'
]
.
objects
.
get
(
pk
=
pk
)
push_system_user_to_node
(
instance
,
node
)
assets
=
kwargs
[
'model'
]
.
objects
.
filter
(
pk__in
=
kwargs
[
'pk_set'
])
push_system_user_to_assets
(
instance
,
assets
)
@receiver
(
m2m_changed
,
sender
=
Asset
.
nodes
.
through
)
def
on_asset_node_changed
(
sender
,
instance
=
None
,
**
kwargs
):
if
isinstance
(
instance
,
Asset
)
and
kwargs
[
'action'
]
==
'post_add'
:
logger
.
debug
(
"Asset node change signal received"
)
for
pk
in
kwargs
[
'pk_set'
]:
node
=
kwargs
[
'model'
]
.
objects
.
get
(
pk
=
pk
)
push_node_system_users_to_asset
(
node
,
[
instance
])
nodes
=
kwargs
[
'model'
]
.
objects
.
filter
(
pk__in
=
kwargs
[
'pk_set'
])
system_users_assets
=
defaultdict
(
set
)
system_users
=
SystemUser
.
objects
.
filter
(
nodes__in
=
nodes
)
for
system_user
in
system_users
:
system_users_assets
[
system_user
]
.
update
({
instance
})
for
system_user
,
assets
in
system_users_assets
.
items
():
system_user
.
assets
.
add
(
*
tuple
(
assets
))
@receiver
(
m2m_changed
,
sender
=
Asset
.
nodes
.
through
)
...
...
@@ -67,5 +79,6 @@ def on_node_assets_changed(sender, instance=None, **kwargs):
if
isinstance
(
instance
,
Node
)
and
kwargs
[
'action'
]
==
'post_add'
:
logger
.
debug
(
"Node assets change signal received"
)
assets
=
kwargs
[
'model'
]
.
objects
.
filter
(
pk__in
=
kwargs
[
'pk_set'
])
push_node_system_users_to_asset
(
instance
,
assets
)
system_users
=
SystemUser
.
objects
.
filter
(
nodes
=
instance
)
for
system_user
in
system_users
:
system_user
.
assets
.
add
(
*
tuple
(
assets
))
apps/assets/tasks.py
View file @
fffa0def
...
...
@@ -386,52 +386,17 @@ def push_system_user_util(system_users, assets, task_name):
return
task
.
run
()
def
get_node_push_system_user_task_name
(
system_user
,
node
):
# return _("Push system user to node: {} => {}").format(
return
_
(
"推送系统用户到节点资产: {} => {}"
)
.
format
(
system_user
.
name
,
node
.
value
)
@shared_task
def
push_system_user_to_node
(
system_user
,
node
):
logger
.
info
(
"Start push system user node: {} => {}"
.
format
(
system_user
.
name
,
node
.
value
))
assets
=
node
.
get_all_assets
()
task_name
=
get_node_push_system_user_task_name
(
system_user
,
node
)
push_system_user_util
([
system_user
],
assets
,
task_name
)
@shared_task
def
push_system_user_related_nodes
(
system_user
):
if
not
system_user
.
is_need_push
():
msg
=
"push system user `{}` passed, may be not auto push or ssh "
\
"protocol is not ssh"
.
format
(
system_user
.
name
)
logger
.
info
(
msg
)
return
nodes
=
system_user
.
nodes
.
all
()
for
node
in
nodes
:
push_system_user_to_node
(
system_user
,
node
)
@shared_task
def
push_system_user_to_assets_manual
(
system_user
):
push_system_user_related_nodes
(
system_user
)
assets
=
system_user
.
get_assets
()
task_name
=
"推送系统用户到入资产: {}"
.
format
(
system_user
.
name
)
return
push_system_user_util
([
system_user
],
assets
,
task_name
=
task_name
)
def
push_node_system_users_to_asset
(
node
,
assets
):
system_users
=
[]
nodes
=
node
.
ancestor_with_node
# 获取该节点所有父节点有的系统用户, 然后推送
for
n
in
nodes
:
system_users
.
extend
(
list
(
n
.
systemuser_set
.
all
()))
if
system_users
:
# task_name = _("Push system users to node: {}").format(node.value)
task_name
=
_
(
"推送节点系统用户到新加入资产中: {}"
)
.
format
(
node
.
valu
e
)
push_system_user_util
.
delay
(
system_users
,
assets
,
task_name
)
@shared_task
def
push_system_user_to_assets
(
system_user
,
assets
):
task_name
=
_
(
"推送系统用户到入资产: {}"
)
.
format
(
system_user
.
nam
e
)
return
push_system_user_util
.
delay
([
system_user
]
,
assets
,
task_name
)
# @shared_task
...
...
apps/assets/templates/assets/asset_create.html
View file @
fffa0def
...
...
@@ -34,7 +34,7 @@
<div
class=
"form-group {% if form.errors.labels %} has-error {% endif %}"
>
<label
for=
"{{ form.labels.id_for_label }}"
class=
"col-md-2 control-label"
>
{% trans 'Label' %}
</label>
<div
class=
"col-md-9"
>
<select
name=
"labels"
class=
"select2 labels"
data-placeholder=
"{% trans '
Select labels
' %}"
style=
"width: 100%"
multiple=
""
tabindex=
"4"
id=
"{{ form.labels.id_for_label }}"
>
<select
name=
"labels"
class=
"select2 labels"
data-placeholder=
"{% trans '
Label
' %}"
style=
"width: 100%"
multiple=
""
tabindex=
"4"
id=
"{{ form.labels.id_for_label }}"
>
{% for name, labels in form.labels.field.queryset|group_labels %}
<optgroup
label=
"{{ name }}"
>
{% for label in labels %}
...
...
apps/assets/templates/assets/asset_update.html
View file @
fffa0def
...
...
@@ -39,7 +39,7 @@
<div
class=
"form-group"
>
<label
for=
"{{ form.labels.id_for_label }}"
class=
"col-md-2 control-label"
>
{% trans 'Label' %}
</label>
<div
class=
"col-md-9"
>
<select
name=
"labels"
class=
"select2 labels"
data-placeholder=
"
Select labels
"
style=
"width: 100%"
multiple=
""
tabindex=
"4"
id=
"{{ form.labels.id_for_label }}"
>
<select
name=
"labels"
class=
"select2 labels"
data-placeholder=
"
{% trans 'Label' %}
"
style=
"width: 100%"
multiple=
""
tabindex=
"4"
id=
"{{ form.labels.id_for_label }}"
>
{% for name, labels in form.labels.field.queryset|group_labels %}
<optgroup
label=
"{{ name }}"
>
{% for label in labels %}
...
...
apps/perms/api.py
View file @
fffa0def
...
...
@@ -7,9 +7,9 @@ from rest_framework.generics import ListAPIView, get_object_or_404
from
rest_framework
import
viewsets
from
users.permissions
import
IsValidUser
,
IsSuperUser
,
IsSuperUserOrAppUser
from
.utils
import
Node
PermissionUtil
from
.models
import
Node
Permission
from
.hands
import
AssetGrantedSerializer
,
User
,
UserGroup
,
Asset
,
\
from
.utils
import
Asset
PermissionUtil
from
.models
import
Asset
Permission
from
.hands
import
AssetGrantedSerializer
,
User
,
UserGroup
,
Asset
,
Node
,
\
NodeGrantedSerializer
,
SystemUser
,
NodeSerializer
from
.
import
serializers
...
...
@@ -18,7 +18,7 @@ class AssetPermissionViewSet(viewsets.ModelViewSet):
"""
资产授权列表的增删改查api
"""
queryset
=
Node
Permission
.
objects
.
all
()
queryset
=
Asset
Permission
.
objects
.
all
()
serializer_class
=
serializers
.
AssetPermissionCreateUpdateSerializer
permission_classes
=
(
IsSuperUser
,)
...
...
@@ -27,15 +27,6 @@ class AssetPermissionViewSet(viewsets.ModelViewSet):
return
serializers
.
AssetPermissionListSerializer
return
self
.
serializer_class
def
get_queryset
(
self
):
queryset
=
super
()
.
get_queryset
()
node_id
=
self
.
request
.
query_params
.
get
(
'node_id'
)
if
node_id
:
queryset
=
queryset
.
filter
(
node__id
=
node_id
)
return
queryset
class
UserGrantedAssetsApi
(
ListAPIView
):
"""
...
...
@@ -53,7 +44,7 @@ class UserGrantedAssetsApi(ListAPIView):
else
:
user
=
self
.
request
.
user
for
k
,
v
in
Node
PermissionUtil
.
get_user_assets
(
user
)
.
items
():
for
k
,
v
in
Asset
PermissionUtil
.
get_user_assets
(
user
)
.
items
():
if
k
.
is_unixlike
():
system_users_granted
=
[
s
for
s
in
v
if
s
.
protocol
==
'ssh'
]
else
:
...
...
@@ -78,14 +69,14 @@ class UserGrantedNodesApi(ListAPIView):
user
=
get_object_or_404
(
User
,
id
=
user_id
)
else
:
user
=
self
.
request
.
user
nodes
=
NodePermissionUtil
.
get_user_node
s
(
user
)
nodes
=
AssetPermissionUtil
.
get_user_nodes_with_asset
s
(
user
)
return
nodes
.
keys
()
class
UserGrantedNodesWithAssetsApi
(
ListAPIView
):
"""
授权用户的资产组,注:这里的资产组并非是授权列表中授权的,
而是把所有资产取出来,然后反查出所有
资产组
,然后合并得到,
而是把所有资产取出来,然后反查出所有
节点
,然后合并得到,
结果里也包含资产组下授权的资产
数据结构如下:
[
...
...
@@ -121,18 +112,12 @@ class UserGrantedNodesWithAssetsApi(ListAPIView):
else
:
user
=
get_object_or_404
(
User
,
id
=
user_id
)
nodes
=
NodePermissionUtil
.
get_user_nodes_with_assets
(
user
)
assets
=
{}
for
k
,
v
in
NodePermissionUtil
.
get_user_assets
(
user
)
.
items
():
if
k
.
is_unixlike
():
system_users_granted
=
[
s
for
s
in
v
if
s
.
protocol
==
'ssh'
]
else
:
system_users_granted
=
[
s
for
s
in
v
if
s
.
protocol
==
'rdp'
]
assets
[
k
]
=
system_users_granted
for
node
,
v
in
nodes
.
items
():
for
asset
in
v
[
'assets'
]:
asset
.
system_users_granted
=
assets
[
asset
]
node
.
assets_granted
=
v
[
'assets'
]
nodes
=
AssetPermissionUtil
.
get_user_nodes_with_assets
(
user
)
for
node
,
_assets
in
nodes
.
items
():
assets
=
_assets
.
keys
()
for
asset
,
system_users
in
_assets
.
items
():
asset
.
system_users_granted
=
system_users
node
.
assets_granted
=
assets
queryset
.
append
(
node
)
return
queryset
...
...
@@ -142,6 +127,26 @@ class UserGrantedNodesWithAssetsApi(ListAPIView):
return
super
()
.
get_permissions
()
class
UserGrantedNodeAssetsApi
(
ListAPIView
):
permission_classes
=
(
IsSuperUserOrAppUser
,)
serializer_class
=
AssetGrantedSerializer
def
get_queryset
(
self
):
user_id
=
self
.
kwargs
.
get
(
'pk'
,
''
)
node_id
=
self
.
kwargs
.
get
(
'node_id'
)
if
user_id
:
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
)
assets
=
nodes
.
get
(
node
,
[])
for
asset
,
system_users
in
assets
.
items
():
asset
.
system_users_granted
=
system_users
return
assets
class
UserGroupGrantedAssetsApi
(
ListAPIView
):
permission_classes
=
(
IsSuperUser
,)
serializer_class
=
AssetGrantedSerializer
...
...
@@ -154,7 +159,7 @@ class UserGroupGrantedAssetsApi(ListAPIView):
return
queryset
user_group
=
get_object_or_404
(
UserGroup
,
id
=
user_group_id
)
assets
=
Node
PermissionUtil
.
get_user_group_assets
(
user_group
)
assets
=
Asset
PermissionUtil
.
get_user_group_assets
(
user_group
)
for
k
,
v
in
assets
.
items
():
k
.
system_users_granted
=
v
queryset
.
append
(
k
)
...
...
@@ -171,8 +176,8 @@ class UserGroupGrantedNodesApi(ListAPIView):
if
group_id
:
group
=
get_object_or_404
(
UserGroup
,
id
=
group_id
)
nodes
=
NodePermissionUtil
.
get_user_group_node
s
(
group
)
queryset
=
nodes
.
keys
()
nodes
=
AssetPermissionUtil
.
get_user_group_nodes_with_asset
s
(
group
)
return
nodes
.
keys
()
return
queryset
...
...
@@ -188,15 +193,33 @@ class UserGroupGrantedNodesWithAssetsApi(ListAPIView):
return
queryset
user_group
=
get_object_or_404
(
UserGroup
,
id
=
user_group_id
)
nodes
=
NodePermissionUtil
.
get_user_group_nodes_with_assets
(
user_group
)
for
node
,
v
in
nodes
.
items
():
for
asset
in
v
[
'assets'
]:
asset
.
system_users_granted
=
v
[
'system_users'
]
node
.
assets_granted
=
v
[
'assets'
]
nodes
=
AssetPermissionUtil
.
get_user_group_nodes_with_assets
(
user_group
)
for
node
,
_assets
in
nodes
.
items
():
assets
=
_assets
.
keys
()
for
asset
,
system_users
in
_assets
.
items
():
asset
.
system_users_granted
=
system_users
node
.
assets_granted
=
assets
queryset
.
append
(
node
)
return
queryset
class
UserGroupGrantedNodeAssetsApi
(
ListAPIView
):
permission_classes
=
(
IsSuperUserOrAppUser
,)
serializer_class
=
AssetGrantedSerializer
def
get_queryset
(
self
):
user_group_id
=
self
.
kwargs
.
get
(
'pk'
,
''
)
node_id
=
self
.
kwargs
.
get
(
'node_id'
)
user_group
=
get_object_or_404
(
UserGroup
,
id
=
user_group_id
)
node
=
get_object_or_404
(
Node
,
id
=
node_id
)
nodes
=
AssetPermissionUtil
.
get_user_group_nodes_with_assets
(
user_group
)
assets
=
nodes
.
get
(
node
,
[])
for
asset
,
system_users
in
assets
.
items
():
asset
.
system_users_granted
=
system_users
return
assets
class
ValidateUserAssetPermissionView
(
APIView
):
permission_classes
=
(
IsSuperUserOrAppUser
,)
...
...
@@ -210,7 +233,7 @@ class ValidateUserAssetPermissionView(APIView):
asset
=
get_object_or_404
(
Asset
,
id
=
asset_id
)
system_user
=
get_object_or_404
(
SystemUser
,
id
=
system_id
)
assets_granted
=
Node
PermissionUtil
.
get_user_assets
(
user
)
assets_granted
=
Asset
PermissionUtil
.
get_user_assets
(
user
)
if
system_user
in
assets_granted
.
get
(
asset
,
[]):
return
Response
({
'msg'
:
True
},
status
=
200
)
else
:
...
...
apps/perms/serializers.py
View file @
fffa0def
# -*- coding: utf-8 -*-
#
from
django.utils.translation
import
ugettext_lazy
as
_
from
rest_framework
import
serializers
from
common.utils
import
get_object_or_none
from
common.fields
import
StringIDField
from
.models
import
AssetPermission
,
NodePermission
from
.models
import
AssetPermission
class
AssetPermissionCreateUpdateSerializer
(
serializers
.
ModelSerializer
):
class
Meta
:
model
=
NodePermission
fields
=
[
'id'
,
'node'
,
'user_group'
,
'system_user'
,
'is_active'
,
'date_expired'
]
model
=
AssetPermission
exclude
=
(
'id'
,
'create_by'
,
'date_created'
)
class
AssetPermissionListSerializer
(
serializers
.
ModelSerializer
):
node
=
StringIDField
(
read_only
=
True
)
user_group
=
StringIDField
(
read_only
=
True
)
system_user
=
StringIDField
(
read_only
=
True
)
class
Meta
:
model
=
Node
Permission
model
=
Asset
Permission
fields
=
'__all__'
...
...
@@ -40,14 +30,3 @@ class AssetPermissionUpdateAssetSerializer(serializers.ModelSerializer):
model
=
AssetPermission
fields
=
[
'id'
,
'assets'
]
class
UserAssetPermissionCreateUpdateSerializer
(
AssetPermissionCreateUpdateSerializer
):
is_inherited
=
serializers
.
SerializerMethodField
()
@staticmethod
def
get_is_inherited
(
obj
):
if
getattr
(
obj
,
'inherited'
,
''
):
return
True
else
:
return
False
apps/perms/signals_handler.py
View file @
fffa0def
# -*- coding: utf-8 -*-
#
from
django.db.models.signals
import
post_save
,
post_delete
from
django.db.models.signals
import
m2m_changed
from
django.dispatch
import
receiver
from
common.utils
import
get_logger
from
.models
import
Node
Permission
from
.models
import
Asset
Permission
logger
=
get_logger
(
__file__
)
@receiver
(
post_save
,
sender
=
NodePermission
,
dispatch_uid
=
"my_unique_identifier"
)
def
on_asset_permission_create_or_update
(
sender
,
instance
=
None
,
**
kwargs
):
if
instance
and
instance
.
node
and
instance
.
system_user
:
instance
.
system_user
.
nodes
.
add
(
instance
.
node
)
@receiver
(
m2m_changed
,
sender
=
AssetPermission
.
nodes
.
through
)
def
on_permission_nodes_changed
(
sender
,
instance
=
None
,
**
kwargs
):
if
isinstance
(
instance
,
AssetPermission
)
and
kwargs
[
'action'
]
==
'post_add'
:
logger
.
debug
(
"Asset permission nodes change signal received"
)
nodes
=
kwargs
[
'model'
]
.
objects
.
filter
(
pk__in
=
kwargs
[
'pk_set'
])
system_users
=
instance
.
system_users
.
all
()
for
system_user
in
system_users
:
system_user
.
nodes
.
add
(
*
tuple
(
nodes
))
@receiver
(
m2m_changed
,
sender
=
AssetPermission
.
assets
.
through
)
def
on_permission_assets_changed
(
sender
,
instance
=
None
,
**
kwargs
):
if
isinstance
(
instance
,
AssetPermission
)
and
kwargs
[
'action'
]
==
'post_add'
:
logger
.
debug
(
"Asset permission assets change signal received"
)
assets
=
kwargs
[
'model'
]
.
objects
.
filter
(
pk__in
=
kwargs
[
'pk_set'
])
system_users
=
instance
.
system_users
.
all
()
for
system_user
in
system_users
:
system_user
.
assets
.
add
(
*
tuple
(
assets
))
@receiver
(
m2m_changed
,
sender
=
AssetPermission
.
system_users
.
through
)
def
on_permission_system_users_changed
(
sender
,
instance
=
None
,
**
kwargs
):
if
isinstance
(
instance
,
AssetPermission
)
and
kwargs
[
'action'
]
==
'post_add'
:
logger
.
debug
(
"Asset permission system_users change signal received"
)
system_users
=
kwargs
[
'model'
]
.
objects
.
filter
(
pk__in
=
kwargs
[
'pk_set'
])
assets
=
instance
.
assets
.
all
()
nodes
=
instance
.
nodes
.
all
()
for
system_user
in
system_users
:
system_user
.
nodes
.
add
(
*
tuple
(
nodes
))
system_user
.
assets
.
add
(
*
tuple
(
assets
))
apps/perms/templates/perms/asset_permission_list.html
View file @
fffa0def
...
...
@@ -116,7 +116,7 @@
</td>
<td
class=
"text-center"
>
<a
href=
"{% url 'perms:asset-permission-update' pk=object.id %}"
class=
"btn btn-xs btn-info"
>
{% trans "Update" %}
</a>
<a
href=
""
class=
"btn btn-xs btn-danger m-l-xs
"
>
{% trans "Delete" %}
</a>
<a
data-uid=
"{{ object.id }}"
class=
"btn btn-xs btn-danger m-l-xs btn-delete
"
>
{% trans "Delete" %}
</a>
</td>
<td>
{{ object.users_detail }}
</td>
<td>
{{ object.user_groups_detail }}
</td>
...
...
@@ -147,6 +147,15 @@
calendarWeeks
:
true
,
autoclose
:
true
});
}).
on
(
'click'
,
'.btn-delete'
,
function
()
{
var
$this
=
$
(
this
);
var
uid
=
$this
.
data
(
'uid'
);
var
the_url
=
'{% url "api-perms:asset-permission-detail" pk=DEFAULT_PK %}'
.
replace
(
'{{ DEFAULT_PK }}'
,
uid
);
var
name
=
$
(
this
).
closest
(
"tr"
).
find
(
":nth-child(2)"
).
children
(
'a'
).
html
();
objectDelete
(
$this
,
name
,
the_url
);
setTimeout
(
function
()
{
window
.
reload
();
},
1000
);
});
</script>
{% endblock %}
...
...
apps/perms/urls/api_urls.py
View file @
fffa0def
...
...
@@ -15,6 +15,8 @@ urlpatterns = [
url
(
r'^v1/user/assets/$'
,
api
.
UserGrantedAssetsApi
.
as_view
(),
name
=
'my-assets'
),
url
(
r'^v1/user/(?P<pk>[0-9a-zA-Z\-]{36})/nodes/$'
,
api
.
UserGrantedNodesApi
.
as_view
(),
name
=
'user-nodes'
),
url
(
r'^v1/user/nodes/$'
,
api
.
UserGrantedNodesApi
.
as_view
(),
name
=
'my-nodes'
),
url
(
r'^v1/user/(?P<pk>[0-9a-zA-Z\-]{36})/nodes/(?P<node_id>[0-9a-zA-Z\-]{36})/assets/$'
,
api
.
UserGrantedNodeAssetsApi
.
as_view
(),
name
=
'user-node-assets'
),
url
(
r'^v1/user/nodes/(?P<node_id>[0-9a-zA-Z\-]{36})/assets/$'
,
api
.
UserGrantedNodeAssetsApi
.
as_view
(),
name
=
'my-node-assets'
),
url
(
r'^v1/user/(?P<pk>[0-9a-zA-Z\-]{36})/nodes-assets/$'
,
api
.
UserGrantedNodesWithAssetsApi
.
as_view
(),
name
=
'user-nodes-assets'
),
url
(
r'^v1/user/nodes-assets/$'
,
api
.
UserGrantedNodesWithAssetsApi
.
as_view
(),
name
=
'my-nodes-assets'
),
...
...
@@ -22,6 +24,7 @@ urlpatterns = [
url
(
r'^v1/user-group/(?P<pk>[0-9a-zA-Z\-]{36})/assets/$'
,
api
.
UserGroupGrantedAssetsApi
.
as_view
(),
name
=
'user-group-assets'
),
url
(
r'^v1/user-group/(?P<pk>[0-9a-zA-Z\-]{36})/nodes/$'
,
api
.
UserGroupGrantedNodesApi
.
as_view
(),
name
=
'user-group-nodes'
),
url
(
r'^v1/user-group/(?P<pk>[0-9a-zA-Z\-]{36})/nodes-assets/$'
,
api
.
UserGroupGrantedNodesWithAssetsApi
.
as_view
(),
name
=
'user-group-nodes-assets'
),
url
(
r'^v1/user-group/(?P<pk>[0-9a-zA-Z\-]{36})/nodes/(?P<node_id>[0-9a-zA-Z\-]{36})/assets/$'
,
api
.
UserGroupGrantedNodeAssetsApi
.
as_view
(),
name
=
'user-group-node-assets'
),
# 验证用户是否有某个资产和系统用户的权限
url
(
r'v1/asset-permission/user/validate/$'
,
api
.
ValidateUserAssetPermissionView
.
as_view
(),
name
=
'validate-user-asset-permission'
),
...
...
apps/perms/utils.py
View file @
fffa0def
...
...
@@ -12,7 +12,7 @@ from .models import AssetPermission
logger
=
get_logger
(
__file__
)
class
AssetPermissionUtil
s
:
class
AssetPermissionUtil
:
@staticmethod
def
get_user_permissions
(
user
):
...
...
@@ -81,6 +81,23 @@ class AssetPermissionUtils:
assets
[
asset
]
.
update
(
set
(
_system_users
))
return
assets
@classmethod
def
get_user_group_nodes_with_assets
(
cls
,
user
):
"""
:param user:
:return: {node: {asset: set(su1, su2)}}
"""
nodes
=
defaultdict
(
dict
)
_assets
=
cls
.
get_user_group_assets
(
user
)
for
asset
,
_system_users
in
_assets
.
items
():
_nodes
=
asset
.
get_nodes
()
for
node
in
_nodes
:
if
asset
in
nodes
[
node
]:
nodes
[
node
][
asset
]
.
update
(
_system_users
)
else
:
nodes
[
node
][
asset
]
=
_system_users
return
nodes
@classmethod
def
get_user_assets_direct
(
cls
,
user
):
assets
=
defaultdict
(
set
)
...
...
@@ -142,7 +159,7 @@ class AssetPermissionUtils:
return
assets
@classmethod
def
get_user_node_with_assets
(
cls
,
user
):
def
get_user_node
s
_with_assets
(
cls
,
user
):
"""
:param user:
:return: {node: {asset: set(su1, su2)}}
...
...
@@ -178,8 +195,11 @@ class AssetPermissionUtils:
return
system_users
# Abandon
class
NodePermissionUtil
:
"""
"""
@staticmethod
def
get_user_group_permissions
(
user_group
):
...
...
apps/users/templates/users/user_granted_asset.html
View file @
fffa0def
...
...
@@ -44,7 +44,7 @@
<th
class=
"text-center"
>
{% trans 'Hostname' %}
</th>
<th
class=
"text-center"
>
{% trans 'IP' %}
</th>
<th
class=
"text-center"
>
{% trans 'Active' %}
</th>
<th
class=
"text-center"
>
{% trans '
Reachable
' %}
</th>
<th
class=
"text-center"
>
{% trans '
System users
' %}
</th>
</tr>
</thead>
<tbody>
...
...
@@ -63,6 +63,8 @@
<script>
var
zTree
;
var
inited
=
false
;
var
url
;
var
asset_table
;
function
initTable
()
{
if
(
inited
){
...
...
@@ -86,31 +88,28 @@ function initTable() {
}
}},
{
targets
:
4
,
createdCell
:
function
(
td
,
cellData
)
{
if
(
cellData
===
'Unknown'
){
$
(
td
).
html
(
'<i class="fa fa-circle text-warning"></i>'
)
}
else
if
(
!
cellData
)
{
$
(
td
).
html
(
'<i class="fa fa-circle text-danger"></i>'
)
}
else
{
$
(
td
).
html
(
'<i class="fa fa-circle text-navy"></i>'
)
}
var
users
=
[];
$
.
each
(
cellData
,
function
(
id
,
data
)
{
users
.
push
(
data
.
name
);
});
$
(
td
).
html
(
users
.
join
(
', '
))
}}
],
ajax_url
:
'{% url "api-assets:asset-list" %}'
,
ajax_url
:
url
,
columns
:
[
{
data
:
"id"
},
{
data
:
"hostname"
},
{
data
:
"ip"
},
{
data
:
"is_active"
,
orderable
:
false
},
{
data
:
"
is_connective
"
,
orderable
:
false
}
{
data
:
"
system_users_granted
"
,
orderable
:
false
}
]
};
asset_table
=
jumpserver
.
initServerSideDataTable
(
options
);
return
asset_table
return
jumpserver
.
initDataTable
(
options
);
}
function
onSelected
(
event
,
treeNode
)
{
initTable
();
var
url
=
asset_table
.
ajax
.
url
();
url
=
setUrlParam
(
url
,
"node_id"
,
treeNode
.
id
);
url
=
'{% url "api-perms:user-node-assets" pk=object.id node_id=DEFAULT_PK %}'
;
url
=
url
.
replace
(
"{{ DEFAULT_PK }}"
,
treeNode
.
id
);
setCookie
(
'node_selected'
,
treeNode
.
id
);
asset_table
=
initTable
();
asset_table
.
ajax
.
url
(
url
);
asset_table
.
ajax
.
reload
();
}
...
...
apps/users/templates/users/user_group_granted_asset.html
View file @
fffa0def
...
...
@@ -63,6 +63,7 @@
<script>
var
zTree
;
var
inited
=
false
;
var
url
;
function
initTable
()
{
if
(
inited
){
...
...
@@ -86,31 +87,29 @@ function initTable() {
}
}},
{
targets
:
4
,
createdCell
:
function
(
td
,
cellData
)
{
if
(
cellData
===
'Unknown'
){
$
(
td
).
html
(
'<i class="fa fa-circle text-warning"></i>'
)
}
else
if
(
!
cellData
)
{
$
(
td
).
html
(
'<i class="fa fa-circle text-danger"></i>'
)
}
else
{
$
(
td
).
html
(
'<i class="fa fa-circle text-navy"></i>'
)
}
var
users
=
[];
$
.
each
(
cellData
,
function
(
id
,
data
)
{
users
.
push
(
data
.
name
);
});
$
(
td
).
html
(
users
.
join
(
', '
))
}}
],
ajax_url
:
'{% url "api-assets:asset-list" %}'
,
ajax_url
:
url
,
columns
:
[
{
data
:
"id"
},
{
data
:
"hostname"
},
{
data
:
"ip"
},
{
data
:
"is_active"
,
orderable
:
false
},
{
data
:
"
is_connective
"
,
orderable
:
false
}
{
data
:
"
system_users_granted
"
,
orderable
:
false
}
]
};
asset_table
=
jumpserver
.
init
ServerSide
DataTable
(
options
);
asset_table
=
jumpserver
.
initDataTable
(
options
);
return
asset_table
}
function
onSelected
(
event
,
treeNode
)
{
initTable
();
var
url
=
asset_table
.
ajax
.
url
();
url
=
setUrlParam
(
url
,
"node_id"
,
treeNode
.
id
);
url
=
'{% url "api-perms:user-group-node-assets" pk=object.id node_id=DEFAULT_PK %}'
;
url
=
url
.
replace
(
"{{ DEFAULT_PK }}"
,
treeNode
.
id
);
setCookie
(
'node_selected'
,
treeNode
.
id
);
asset_table
=
initTable
();
asset_table
.
ajax
.
url
(
url
);
asset_table
.
ajax
.
reload
();
}
...
...
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