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
8e9b3f13
Commit
8e9b3f13
authored
Jun 28, 2019
by
ibuler
Browse files
Options
Browse Files
Download
Plain Diff
[Update] 修改permission actions
parents
48ba1993
320b17c8
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
35 changed files
with
267 additions
and
353 deletions
+267
-353
node.py
apps/assets/api/node.py
+7
-6
asset.py
apps/assets/forms/asset.py
+7
-1
node.py
apps/assets/models/node.py
+12
-8
node.py
apps/assets/serializers/node.py
+5
-4
_asset_list_modal.html
apps/assets/templates/assets/_asset_list_modal.html
+1
-0
_node_tree.html
apps/assets/templates/assets/_node_tree.html
+0
-0
asset_list.html
apps/assets/templates/assets/asset_list.html
+0
-0
utils.py
apps/assets/utils.py
+3
-0
common.py
apps/common/utils/common.py
+6
-9
settings.py
apps/jumpserver/settings.py
+1
-1
django.mo
apps/locale/zh/LC_MESSAGES/django.mo
+0
-0
django.po
apps/locale/zh/LC_MESSAGES/django.po
+0
-0
hands.py
apps/orgs/hands.py
+1
-1
mixins.py
apps/orgs/mixins.py
+23
-4
signals_handler.py
apps/orgs/signals_handler.py
+2
-2
asset_permission.py
apps/perms/api/asset_permission.py
+1
-7
user_permission.py
apps/perms/api/user_permission.py
+1
-1
asset_permission.py
apps/perms/forms/asset_permission.py
+12
-8
0003_auto_20180225_1815.py
apps/perms/migrations/0003_auto_20180225_1815.py
+0
-41
0004_auto_20180411_1135.py
apps/perms/migrations/0004_auto_20180411_1135.py
+0
-31
0005_migrate_data_20180411_1144.py
apps/perms/migrations/0005_migrate_data_20180411_1144.py
+0
-49
0006_auto_20180606_1505.py
apps/perms/migrations/0006_auto_20180606_1505.py
+0
-27
0006_auto_20190628_1921.py
apps/perms/migrations/0006_auto_20190628_1921.py
+45
-0
0007_auto_20180807_1116.py
apps/perms/migrations/0007_auto_20180807_1116.py
+0
-37
0007_remove_assetpermission_actions.py
apps/perms/migrations/0007_remove_assetpermission_actions.py
+5
-5
0008_auto_20180816_1652.py
apps/perms/migrations/0008_auto_20180816_1652.py
+0
-23
asset_permission.py
apps/perms/models/asset_permission.py
+19
-2
asset_permission.py
apps/perms/serializers/asset_permission.py
+2
-8
signals_handler.py
apps/perms/signals_handler.py
+0
-7
asset_permission_create_update.html
...perms/templates/perms/asset_permission_create_update.html
+31
-2
asset_permission_list.html
apps/perms/templates/perms/asset_permission_list.html
+9
-33
api_urls.py
apps/perms/urls/api_urls.py
+0
-1
asset_permission.py
apps/perms/utils/asset_permission.py
+48
-31
asset_permission.py
apps/perms/views/asset_permission.py
+0
-2
jumpserver.js
apps/static/js/jumpserver.js
+26
-2
No files found.
apps/assets/api/node.py
View file @
8e9b3f13
...
@@ -112,12 +112,16 @@ class NodeChildrenAsTreeApi(generics.ListAPIView):
...
@@ -112,12 +112,16 @@ class NodeChildrenAsTreeApi(generics.ListAPIView):
is_root
=
False
is_root
=
False
def
get_queryset
(
self
):
def
get_queryset
(
self
):
self
.
check_need_refresh_nodes
()
node_key
=
self
.
request
.
query_params
.
get
(
'key'
)
node_key
=
self
.
request
.
query_params
.
get
(
'key'
)
util
=
NodeUtil
()
util
=
NodeUtil
()
# 是否包含自己
with_self
=
False
if
not
node_key
:
if
not
node_key
:
node_key
=
Node
.
root
()
.
key
node_key
=
Node
.
root
()
.
key
with_self
=
True
self
.
node
=
util
.
get_node_by_key
(
node_key
)
self
.
node
=
util
.
get_node_by_key
(
node_key
)
queryset
=
self
.
node
.
get_children
(
with_self
=
True
)
queryset
=
self
.
node
.
get_children
(
with_self
=
with_self
)
queryset
=
[
node
.
as_tree_node
()
for
node
in
queryset
]
queryset
=
[
node
.
as_tree_node
()
for
node
in
queryset
]
queryset
=
sorted
(
queryset
)
queryset
=
sorted
(
queryset
)
return
queryset
return
queryset
...
@@ -133,14 +137,11 @@ class NodeChildrenAsTreeApi(generics.ListAPIView):
...
@@ -133,14 +137,11 @@ class NodeChildrenAsTreeApi(generics.ListAPIView):
def
filter_queryset
(
self
,
queryset
):
def
filter_queryset
(
self
,
queryset
):
queryset
=
self
.
filter_assets
(
queryset
)
queryset
=
self
.
filter_assets
(
queryset
)
queryset
=
self
.
filter_refresh_nodes
(
queryset
)
return
queryset
return
queryset
def
filter_refresh_nodes
(
self
,
queryset
):
def
check_need_refresh_nodes
(
self
):
if
self
.
request
.
query_params
.
get
(
'refresh'
,
'0'
)
==
'1'
:
if
self
.
request
.
query_params
.
get
(
'refresh'
,
'0'
)
==
'1'
:
Node
.
expire_nodes_assets_amount
()
Node
.
refresh_nodes
()
Node
.
expire_nodes_full_value
()
return
queryset
class
NodeChildrenApi
(
mixins
.
ListModelMixin
,
generics
.
CreateAPIView
):
class
NodeChildrenApi
(
mixins
.
ListModelMixin
,
generics
.
CreateAPIView
):
...
...
apps/assets/forms/asset.py
View file @
8e9b3f13
...
@@ -6,7 +6,7 @@ from django.utils.translation import gettext_lazy as _
...
@@ -6,7 +6,7 @@ from django.utils.translation import gettext_lazy as _
from
common.utils
import
get_logger
from
common.utils
import
get_logger
from
orgs.mixins
import
OrgModelForm
from
orgs.mixins
import
OrgModelForm
from
..models
import
Asset
,
Protocol
from
..models
import
Asset
,
Protocol
,
Node
logger
=
get_logger
(
__file__
)
logger
=
get_logger
(
__file__
)
...
@@ -33,6 +33,12 @@ class ProtocolForm(forms.ModelForm):
...
@@ -33,6 +33,12 @@ class ProtocolForm(forms.ModelForm):
class
AssetCreateForm
(
OrgModelForm
):
class
AssetCreateForm
(
OrgModelForm
):
PROTOCOL_CHOICES
=
Protocol
.
PROTOCOL_CHOICES
PROTOCOL_CHOICES
=
Protocol
.
PROTOCOL_CHOICES
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
()
.
__init__
(
*
args
,
**
kwargs
)
if
not
self
.
data
:
nodes_field
=
self
.
fields
[
'nodes'
]
nodes_field
.
_queryset
=
Node
.
get_queryset
()
class
Meta
:
class
Meta
:
model
=
Asset
model
=
Asset
fields
=
[
fields
=
[
...
...
apps/assets/models/node.py
View file @
8e9b3f13
...
@@ -186,9 +186,6 @@ class FullValueMixin:
...
@@ -186,9 +186,6 @@ class FullValueMixin:
def
expire_nodes_full_value
(
cls
,
nodes
=
None
):
def
expire_nodes_full_value
(
cls
,
nodes
=
None
):
key
=
cls
.
_full_value_cache_key
.
format
(
'*'
)
key
=
cls
.
_full_value_cache_key
.
format
(
'*'
)
cache
.
delete_pattern
(
key
+
'*'
)
cache
.
delete_pattern
(
key
+
'*'
)
from
..utils
import
NodeUtil
util
=
NodeUtil
()
util
.
set_full_value
()
class
AssetsAmountMixin
:
class
AssetsAmountMixin
:
...
@@ -216,7 +213,7 @@ class AssetsAmountMixin:
...
@@ -216,7 +213,7 @@ class AssetsAmountMixin:
def
assets_amount
(
self
,
value
):
def
assets_amount
(
self
,
value
):
self
.
_assets_amount
=
value
self
.
_assets_amount
=
value
cache_key
=
self
.
_assets_amount_cache_key
.
format
(
self
.
key
)
cache_key
=
self
.
_assets_amount_cache_key
.
format
(
self
.
key
)
cache
.
set
(
cache_key
,
value
,
3600
*
24
)
cache
.
set
(
cache_key
,
value
)
def
expire_assets_amount
(
self
):
def
expire_assets_amount
(
self
):
ancestor_keys
=
self
.
get_ancestor_keys
(
with_self
=
True
)
ancestor_keys
=
self
.
get_ancestor_keys
(
with_self
=
True
)
...
@@ -226,11 +223,15 @@ class AssetsAmountMixin:
...
@@ -226,11 +223,15 @@ class AssetsAmountMixin:
@classmethod
@classmethod
def
expire_nodes_assets_amount
(
cls
,
nodes
=
None
):
def
expire_nodes_assets_amount
(
cls
,
nodes
=
None
):
from
..utils
import
NodeUtil
key
=
cls
.
_assets_amount_cache_key
.
format
(
'*'
)
key
=
cls
.
_assets_amount_cache_key
.
format
(
'*'
)
cache
.
delete_pattern
(
key
)
cache
.
delete_pattern
(
key
)
@classmethod
def
refresh_nodes
(
cls
):
from
..utils
import
NodeUtil
util
=
NodeUtil
(
with_assets_amount
=
True
)
util
=
NodeUtil
(
with_assets_amount
=
True
)
util
.
set_assets_amount
()
util
.
set_assets_amount
()
util
.
set_full_value
()
class
Node
(
OrgModelMixin
,
FamilyMixin
,
FullValueMixin
,
AssetsAmountMixin
):
class
Node
(
OrgModelMixin
,
FamilyMixin
,
FullValueMixin
,
AssetsAmountMixin
):
...
@@ -375,9 +376,7 @@ class Node(OrgModelMixin, FamilyMixin, FullValueMixin, AssetsAmountMixin):
...
@@ -375,9 +376,7 @@ class Node(OrgModelMixin, FamilyMixin, FullValueMixin, AssetsAmountMixin):
def
as_tree_node
(
self
):
def
as_tree_node
(
self
):
from
common.tree
import
TreeNode
from
common.tree
import
TreeNode
from
..serializers
import
NodeSerializer
name
=
'{} ({})'
.
format
(
self
.
value
,
self
.
assets_amount
)
name
=
'{} ({})'
.
format
(
self
.
value
,
self
.
assets_amount
)
node_serializer
=
NodeSerializer
(
instance
=
self
)
data
=
{
data
=
{
'id'
:
self
.
key
,
'id'
:
self
.
key
,
'name'
:
name
,
'name'
:
name
,
...
@@ -386,7 +385,12 @@ class Node(OrgModelMixin, FamilyMixin, FullValueMixin, AssetsAmountMixin):
...
@@ -386,7 +385,12 @@ class Node(OrgModelMixin, FamilyMixin, FullValueMixin, AssetsAmountMixin):
'isParent'
:
True
,
'isParent'
:
True
,
'open'
:
self
.
is_root
(),
'open'
:
self
.
is_root
(),
'meta'
:
{
'meta'
:
{
'node'
:
node_serializer
.
data
,
'node'
:
{
"id"
:
self
.
id
,
"name"
:
self
.
name
,
"value"
:
self
.
value
,
"key"
:
self
.
key
,
},
'type'
:
'node'
'type'
:
'node'
}
}
}
}
...
...
apps/assets/serializers/node.py
View file @
8e9b3f13
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
from
rest_framework
import
serializers
from
rest_framework
import
serializers
from
django.utils.translation
import
ugettext
as
_
from
orgs.mixins
import
BulkOrgResourceModelSerializer
from
orgs.mixins
import
BulkOrgResourceModelSerializer
from
..models
import
Asset
,
Node
from
..models
import
Asset
,
Node
...
@@ -25,11 +26,11 @@ class NodeSerializer(BulkOrgResourceModelSerializer):
...
@@ -25,11 +26,11 @@ class NodeSerializer(BulkOrgResourceModelSerializer):
def
validate_value
(
self
,
data
):
def
validate_value
(
self
,
data
):
instance
=
self
.
instance
if
self
.
instance
else
Node
.
root
()
instance
=
self
.
instance
if
self
.
instance
else
Node
.
root
()
children
=
instance
.
parent
.
get_children
()
.
exclude
(
key
=
instance
.
key
)
children
=
instance
.
parent
.
get_children
()
values
=
[
child
.
value
for
child
in
children
]
children_values
=
[
node
.
value
for
node
in
children
if
node
!=
instance
]
if
data
in
values
:
if
data
in
children_
values
:
raise
serializers
.
ValidationError
(
raise
serializers
.
ValidationError
(
'The same level node name cannot be the same'
_
(
'The same level node name cannot be the same'
)
)
)
return
data
return
data
...
...
apps/assets/templates/assets/_asset_list_modal.html
View file @
8e9b3f13
...
@@ -67,6 +67,7 @@ function initTable2() {
...
@@ -67,6 +67,7 @@ function initTable2() {
columns
:
[
columns
:
[
{
data
:
"id"
},
{
data
:
"hostname"
},
{
data
:
"ip"
}
{
data
:
"id"
},
{
data
:
"hostname"
},
{
data
:
"ip"
}
],
],
lengthMenu
:
[[
10
,
25
,
50
],
[
10
,
25
,
50
]],
pageLength
:
10
pageLength
:
10
};
};
asset_table2
=
jumpserver
.
initServerSideDataTable
(
options
);
asset_table2
=
jumpserver
.
initServerSideDataTable
(
options
);
...
...
apps/assets/templates/assets/_node_tree.html
0 → 100644
View file @
8e9b3f13
This diff is collapsed.
Click to expand it.
apps/assets/templates/assets/asset_list.html
View file @
8e9b3f13
This diff is collapsed.
Click to expand it.
apps/assets/utils.py
View file @
8e9b3f13
# ~*~ coding: utf-8 ~*~
# ~*~ coding: utf-8 ~*~
#
#
import
time
from
django.db.models
import
Prefetch
from
django.db.models
import
Prefetch
from
common.utils
import
get_object_or_none
,
get_logger
from
common.utils
import
get_object_or_none
,
get_logger
...
@@ -56,9 +57,11 @@ class NodeUtil:
...
@@ -56,9 +57,11 @@ class NodeUtil:
def
get_all_nodes
(
self
):
def
get_all_nodes
(
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
)
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
)
all_nodes
=
sorted
(
all_nodes
,
key
=
self
.
sorted_by
)
...
...
apps/common/utils/common.py
View file @
8e9b3f13
...
@@ -130,16 +130,13 @@ def get_short_uuid_str():
...
@@ -130,16 +130,13 @@ def get_short_uuid_str():
def
is_uuid
(
seq
):
def
is_uuid
(
seq
):
if
isinstance
(
seq
,
str
):
if
isinstance
(
seq
,
uuid
.
UUID
):
if
UUID_PATTERN
.
match
(
seq
):
return
True
return
True
elif
isinstance
(
seq
,
str
)
and
UUID_PATTERN
.
match
(
seq
):
else
:
return
False
else
:
for
s
in
seq
:
if
not
is_uuid
(
s
):
return
False
return
True
return
True
elif
isinstance
(
seq
,
(
list
,
tuple
)):
all
([
is_uuid
(
x
)
for
x
in
seq
])
return
False
def
get_request_ip
(
request
):
def
get_request_ip
(
request
):
...
...
apps/jumpserver/settings.py
View file @
8e9b3f13
...
@@ -399,7 +399,7 @@ REST_FRAMEWORK = {
...
@@ -399,7 +399,7 @@ REST_FRAMEWORK = {
'ORDERING_PARAM'
:
"order"
,
'ORDERING_PARAM'
:
"order"
,
'SEARCH_PARAM'
:
"search"
,
'SEARCH_PARAM'
:
"search"
,
'DATETIME_FORMAT'
:
'
%
Y-
%
m-
%
d
%
H:
%
M:
%
S
%
z'
,
'DATETIME_FORMAT'
:
'
%
Y-
%
m-
%
d
%
H:
%
M:
%
S
%
z'
,
'DATETIME_INPUT_FORMATS'
:
[
'
%
Y-
%
m-
%
d
%
H:
%
M:
%
S
%
z'
],
'DATETIME_INPUT_FORMATS'
:
[
'
iso-8601'
,
'
%
Y-
%
m-
%
d
%
H:
%
M:
%
S
%
z'
],
# 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
# 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
# 'PAGE_SIZE': 15
# 'PAGE_SIZE': 15
}
}
...
...
apps/locale/zh/LC_MESSAGES/django.mo
View file @
8e9b3f13
No preview for this file type
apps/locale/zh/LC_MESSAGES/django.po
View file @
8e9b3f13
This diff is collapsed.
Click to expand it.
apps/orgs/hands.py
View file @
8e9b3f13
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
#
#
from
assets.models
import
Node
from
assets.models
import
Node
from
orgs.utils
import
set_current_org
,
current_org
from
orgs.utils
import
set_current_org
,
current_org
,
get_current_org
apps/orgs/mixins.py
View file @
8e9b3f13
...
@@ -4,7 +4,8 @@ import traceback
...
@@ -4,7 +4,8 @@ import traceback
from
django.db
import
models
from
django.db
import
models
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.shortcuts
import
redirect
,
get_object_or_404
from
django.shortcuts
import
redirect
,
get_object_or_404
from
django.forms
import
ModelForm
from
django
import
forms
from
django.core.exceptions
import
ValidationError
from
django.http.response
import
HttpResponseForbidden
from
django.http.response
import
HttpResponseForbidden
from
rest_framework
import
serializers
from
rest_framework
import
serializers
from
rest_framework.validators
import
UniqueTogetherValidator
from
rest_framework.validators
import
UniqueTogetherValidator
...
@@ -101,6 +102,26 @@ class OrgModelMixin(models.Model):
...
@@ -101,6 +102,26 @@ class OrgModelMixin(models.Model):
else
:
else
:
return
name
return
name
def
validate_unique
(
self
,
exclude
=
None
):
"""
Check unique constraints on the model and raise ValidationError if any
failed.
Form 提交时会使用这个检验
"""
self
.
org_id
=
current_org
.
id
if
current_org
.
is_real
()
else
''
if
exclude
and
'org_id'
in
exclude
:
exclude
.
remove
(
'org_id'
)
unique_checks
,
date_checks
=
self
.
_get_unique_checks
(
exclude
=
exclude
)
errors
=
self
.
_perform_unique_checks
(
unique_checks
)
date_errors
=
self
.
_perform_date_checks
(
date_checks
)
for
k
,
v
in
date_errors
.
items
():
errors
.
setdefault
(
k
,
[])
.
extend
(
v
)
if
errors
:
raise
ValidationError
(
errors
)
class
Meta
:
class
Meta
:
abstract
=
True
abstract
=
True
...
@@ -123,11 +144,9 @@ class RootOrgViewMixin:
...
@@ -123,11 +144,9 @@ class RootOrgViewMixin:
return
super
()
.
dispatch
(
request
,
*
args
,
**
kwargs
)
return
super
()
.
dispatch
(
request
,
*
args
,
**
kwargs
)
class
OrgModelForm
(
ModelForm
):
class
OrgModelForm
(
forms
.
ModelForm
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
()
.
__init__
(
*
args
,
**
kwargs
)
super
()
.
__init__
(
*
args
,
**
kwargs
)
# if 'initial' not in kwargs:
# return
for
name
,
field
in
self
.
fields
.
items
():
for
name
,
field
in
self
.
fields
.
items
():
if
not
hasattr
(
field
,
'queryset'
):
if
not
hasattr
(
field
,
'queryset'
):
continue
continue
...
...
apps/orgs/signals_handler.py
View file @
8e9b3f13
...
@@ -6,7 +6,7 @@ from django.db.models.signals import post_save
...
@@ -6,7 +6,7 @@ from django.db.models.signals import post_save
from
django.dispatch
import
receiver
from
django.dispatch
import
receiver
from
.models
import
Organization
from
.models
import
Organization
from
.hands
import
set_current_org
,
current_org
,
Node
from
.hands
import
set_current_org
,
current_org
,
Node
,
get_current_org
from
perms.models
import
AssetPermission
from
perms.models
import
AssetPermission
from
users.models
import
UserGroup
from
users.models
import
UserGroup
...
@@ -14,7 +14,7 @@ from users.models import UserGroup
...
@@ -14,7 +14,7 @@ from users.models import UserGroup
@receiver
(
post_save
,
sender
=
Organization
)
@receiver
(
post_save
,
sender
=
Organization
)
def
on_org_create_or_update
(
sender
,
instance
=
None
,
created
=
False
,
**
kwargs
):
def
on_org_create_or_update
(
sender
,
instance
=
None
,
created
=
False
,
**
kwargs
):
if
instance
:
if
instance
:
old_org
=
current_org
old_org
=
get_current_org
()
set_current_org
(
instance
)
set_current_org
(
instance
)
node_root
=
Node
.
root
()
node_root
=
Node
.
root
()
if
node_root
.
value
!=
instance
.
name
:
if
node_root
.
value
!=
instance
.
name
:
...
...
apps/perms/api/asset_permission.py
View file @
8e9b3f13
...
@@ -20,16 +20,10 @@ from .. import serializers
...
@@ -20,16 +20,10 @@ from .. import serializers
__all__
=
[
__all__
=
[
'AssetPermissionViewSet'
,
'AssetPermissionRemoveUserApi'
,
'AssetPermissionViewSet'
,
'AssetPermissionRemoveUserApi'
,
'AssetPermissionAddUserApi'
,
'AssetPermissionRemoveAssetApi'
,
'AssetPermissionAddUserApi'
,
'AssetPermissionRemoveAssetApi'
,
'AssetPermissionAddAssetApi'
,
'ActionViewSet'
,
'AssetPermissionAddAssetApi'
,
]
]
class
ActionViewSet
(
viewsets
.
ReadOnlyModelViewSet
):
queryset
=
Action
.
objects
.
all
()
serializer_class
=
serializers
.
ActionSerializer
permission_classes
=
(
IsOrgAdmin
,)
class
AssetPermissionViewSet
(
viewsets
.
ModelViewSet
):
class
AssetPermissionViewSet
(
viewsets
.
ModelViewSet
):
"""
"""
资产授权列表的增删改查api
资产授权列表的增删改查api
...
...
apps/perms/api/user_permission.py
View file @
8e9b3f13
...
@@ -14,7 +14,6 @@ from rest_framework.pagination import LimitOffsetPagination
...
@@ -14,7 +14,6 @@ from rest_framework.pagination import LimitOffsetPagination
from
common.permissions
import
IsValidUser
,
IsOrgAdminOrAppUser
from
common.permissions
import
IsValidUser
,
IsOrgAdminOrAppUser
from
common.tree
import
TreeNodeSerializer
from
common.tree
import
TreeNodeSerializer
from
common.utils
import
get_logger
from
common.utils
import
get_logger
from
orgs.utils
import
set_to_root_org
from
..utils
import
(
from
..utils
import
(
AssetPermissionUtil
,
parse_asset_to_tree_node
,
parse_node_to_tree_node
,
AssetPermissionUtil
,
parse_asset_to_tree_node
,
parse_node_to_tree_node
,
check_system_user_action
,
RemoteAppPermissionUtil
,
check_system_user_action
,
RemoteAppPermissionUtil
,
...
@@ -515,6 +514,7 @@ class ValidateUserRemoteAppPermissionApi(APIView):
...
@@ -515,6 +514,7 @@ class ValidateUserRemoteAppPermissionApi(APIView):
permission_classes
=
(
IsOrgAdminOrAppUser
,)
permission_classes
=
(
IsOrgAdminOrAppUser
,)
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
self
.
change_org_if_need
(
request
,
kwargs
)
user_id
=
request
.
query_params
.
get
(
'user_id'
,
''
)
user_id
=
request
.
query_params
.
get
(
'user_id'
,
''
)
remote_app_id
=
request
.
query_params
.
get
(
'remote_app_id'
,
''
)
remote_app_id
=
request
.
query_params
.
get
(
'remote_app_id'
,
''
)
user
=
get_object_or_404
(
User
,
id
=
user_id
)
user
=
get_object_or_404
(
User
,
id
=
user_id
)
...
...
apps/perms/forms/asset_permission.py
View file @
8e9b3f13
# ~*~ coding: utf-8 ~*~
# ~*~ coding: utf-8 ~*~
from
__future__
import
absolute_import
,
unicode_literals
from
__future__
import
absolute_import
,
unicode_literals
from
functools
import
reduce
from
django
import
forms
from
django
import
forms
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
...
@@ -18,17 +19,22 @@ class AssetPermissionForm(OrgModelForm):
...
@@ -18,17 +19,22 @@ class AssetPermissionForm(OrgModelForm):
def
__init__
(
self
,
*
args
,
**
kwargs
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
()
.
__init__
(
*
args
,
**
kwargs
)
super
()
.
__init__
(
*
args
,
**
kwargs
)
users_field
=
self
.
fields
.
get
(
'users'
)
users_field
=
self
.
fields
.
get
(
'users'
)
if
hasattr
(
users_field
,
'queryset'
):
users_field
.
queryset
=
current_org
.
get_org_users
()
users_field
.
queryset
=
current_org
.
get_org_users
()
assets_field
=
self
.
fields
.
get
(
'assets'
)
# 前端渲染优化, 防止过多资产
# 前端渲染优化, 防止过多资产
if
not
self
.
data
:
if
not
self
.
data
:
instance
=
kwargs
.
get
(
'instance'
)
instance
=
kwargs
.
get
(
'instance'
)
assets_field
=
self
.
fields
[
'assets'
]
if
instance
:
if
instance
:
assets_field
.
queryset
=
instance
.
assets
.
all
()
assets_field
.
queryset
=
instance
.
assets
.
all
()
else
:
else
:
assets_field
.
queryset
=
Asset
.
objects
.
none
()
assets_field
.
queryset
=
Asset
.
objects
.
none
()
nodes_field
=
self
.
fields
[
'nodes'
]
nodes_field
.
_queryset
=
Node
.
get_queryset
()
def
clean_action
(
self
):
actions
=
self
.
cleaned_data
.
get
(
"action"
)
return
reduce
(
lambda
x
,
y
:
x
|
y
,
actions
)
class
Meta
:
class
Meta
:
model
=
AssetPermission
model
=
AssetPermission
...
@@ -51,16 +57,14 @@ class AssetPermissionForm(OrgModelForm):
...
@@ -51,16 +57,14 @@ 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'
)}
),
),
'actions'
:
forms
.
SelectMultiple
(
'action'
:
forms
.
CheckboxSelectMultiple
()
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Action'
)}
)
}
}
labels
=
{
labels
=
{
'nodes'
:
_
(
"Node"
),
'nodes'
:
_
(
"Node"
),
}
}
help_texts
=
{
help_texts
=
{
'action
s
'
:
_
(
'Tips: The RDP protocol does not support separate '
'action'
:
_
(
'Tips: The RDP protocol does not support separate '
'controls for uploading or downloading files'
)
'controls for uploading or downloading files'
)
}
}
def
clean_user_groups
(
self
):
def
clean_user_groups
(
self
):
...
...
apps/perms/migrations/0003_auto_20180225_1815.py
deleted
100644 → 0
View file @
48ba1993
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2018-02-25 10:15
from
__future__
import
unicode_literals
import
common.utils
from
django.db
import
migrations
,
models
import
django.db.models.deletion
import
uuid
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'users'
,
'0004_auto_20180125_1218'
),
(
'assets'
,
'0007_auto_20180225_1815'
),
(
'perms'
,
'0002_auto_20171228_0025'
),
]
operations
=
[
migrations
.
CreateModel
(
name
=
'NodePermission'
,
fields
=
[
(
'id'
,
models
.
UUIDField
(
default
=
uuid
.
uuid4
,
primary_key
=
True
,
serialize
=
False
)),
(
'is_active'
,
models
.
BooleanField
(
default
=
True
,
verbose_name
=
'Active'
)),
(
'date_expired'
,
models
.
DateTimeField
(
default
=
common
.
utils
.
date_expired_default
,
verbose_name
=
'Date expired'
)),
(
'created_by'
,
models
.
CharField
(
blank
=
True
,
max_length
=
128
,
verbose_name
=
'Created by'
)),
(
'date_created'
,
models
.
DateTimeField
(
auto_now_add
=
True
,
verbose_name
=
'Date created'
)),
(
'comment'
,
models
.
TextField
(
blank
=
True
,
verbose_name
=
'Comment'
)),
(
'node'
,
models
.
ForeignKey
(
on_delete
=
django
.
db
.
models
.
deletion
.
CASCADE
,
to
=
'assets.Node'
,
verbose_name
=
'Node'
)),
(
'system_user'
,
models
.
ForeignKey
(
on_delete
=
django
.
db
.
models
.
deletion
.
CASCADE
,
to
=
'assets.SystemUser'
,
verbose_name
=
'System user'
)),
(
'user_group'
,
models
.
ForeignKey
(
on_delete
=
django
.
db
.
models
.
deletion
.
CASCADE
,
to
=
'users.UserGroup'
,
verbose_name
=
'User group'
)),
],
options
=
{
'verbose_name'
:
'Asset permission'
,
},
),
migrations
.
AlterUniqueTogether
(
name
=
'nodepermission'
,
unique_together
=
set
([(
'node'
,
'user_group'
,
'system_user'
)]),
),
]
apps/perms/migrations/0004_auto_20180411_1135.py
deleted
100644 → 0
View file @
48ba1993
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2018-04-11 03:35
from
__future__
import
unicode_literals
from
django.db
import
migrations
,
models
import
django.utils.timezone
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'assets'
,
'0013_auto_20180411_1135'
),
(
'perms'
,
'0003_auto_20180225_1815'
),
]
operations
=
[
migrations
.
RemoveField
(
model_name
=
'assetpermission'
,
name
=
'asset_groups'
,
),
migrations
.
AddField
(
model_name
=
'assetpermission'
,
name
=
'date_start'
,
field
=
models
.
DateTimeField
(
default
=
django
.
utils
.
timezone
.
now
,
verbose_name
=
'Date start'
),
),
migrations
.
AddField
(
model_name
=
'assetpermission'
,
name
=
'nodes'
,
field
=
models
.
ManyToManyField
(
blank
=
True
,
related_name
=
'granted_by_permissions'
,
to
=
'assets.Node'
,
verbose_name
=
'Nodes'
),
),
]
apps/perms/migrations/0005_migrate_data_20180411_1144.py
deleted
100644 → 0
View file @
48ba1993
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2018-04-11 03:35
from
__future__
import
unicode_literals
from
django.db
import
migrations
,
models
import
django.utils.timezone
def
migrate_node_permissions
(
apps
,
schema_editor
):
node_perm_model
=
apps
.
get_model
(
"perms"
,
"NodePermission"
)
asset_perm_model
=
apps
.
get_model
(
"perms"
,
"AssetPermission"
)
db_alias
=
schema_editor
.
connection
.
alias
for
old
in
node_perm_model
.
objects
.
using
(
db_alias
)
.
all
():
perm
=
asset_perm_model
.
objects
.
using
(
db_alias
)
.
create
(
name
=
"{}-{}-{}"
.
format
(
old
.
node
.
value
,
old
.
user_group
.
name
,
old
.
system_user
.
name
),
is_active
=
old
.
is_active
,
date_expired
=
old
.
date_expired
,
created_by
=
old
.
date_expired
,
date_created
=
old
.
date_created
,
comment
=
old
.
comment
,
)
perm
.
user_groups
.
add
(
old
.
user_group
)
perm
.
nodes
.
add
(
old
.
node
)
perm
.
system_users
.
add
(
old
.
system_user
)
def
migrate_system_assets_relation
(
apps
,
schema_editor
):
system_user_model
=
apps
.
get_model
(
"assets"
,
"SystemUser"
)
db_alias
=
schema_editor
.
connection
.
alias
for
s
in
system_user_model
.
objects
.
using
(
db_alias
)
.
all
():
nodes
=
list
(
s
.
nodes
.
all
())
s
.
nodes
.
set
([])
s
.
nodes
.
set
(
nodes
)
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'perms'
,
'0004_auto_20180411_1135'
),
]
operations
=
[
migrations
.
RunPython
(
migrate_node_permissions
),
migrations
.
RunPython
(
migrate_system_assets_relation
),
]
apps/perms/migrations/0006_auto_20180606_1505.py
deleted
100644 → 0
View file @
48ba1993
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2018-06-06 07:05
from
__future__
import
unicode_literals
import
common.utils
from
django.db
import
migrations
,
models
import
django.utils.timezone
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'perms'
,
'0005_migrate_data_20180411_1144'
),
]
operations
=
[
migrations
.
AlterField
(
model_name
=
'assetpermission'
,
name
=
'date_expired'
,
field
=
models
.
DateTimeField
(
db_index
=
True
,
default
=
common
.
utils
.
date_expired_default
,
verbose_name
=
'Date expired'
),
),
migrations
.
AlterField
(
model_name
=
'assetpermission'
,
name
=
'date_start'
,
field
=
models
.
DateTimeField
(
db_index
=
True
,
default
=
django
.
utils
.
timezone
.
now
,
verbose_name
=
'Date start'
),
),
]
apps/perms/migrations/0006_auto_20190628_1921.py
0 → 100644
View file @
8e9b3f13
# Generated by Django 2.1.7 on 2019-06-28 11:47
from
django.db
import
migrations
,
models
from
functools
import
reduce
def
migrate_old_actions
(
apps
,
schema_editor
):
from
orgs.utils
import
set_to_root_org
from
..models
import
ActionFlag
set_to_root_org
()
perm_model
=
apps
.
get_model
(
'perms'
,
'AssetPermission'
)
db_alias
=
schema_editor
.
connection
.
alias
perms
=
perm_model
.
objects
.
using
(
db_alias
)
.
all
()
actions_map
=
{
"all"
:
ActionFlag
.
ALL
,
"connect"
:
ActionFlag
.
CONNECT
,
"upload_file"
:
ActionFlag
.
UPLOAD
,
"download_file"
:
ActionFlag
.
DOWNLOAD
,
}
for
perm
in
perms
:
actions
=
perm
.
actions
.
all
()
new_actions
=
[
actions_map
.
get
(
action
.
name
,
ActionFlag
.
ALL
)
for
action
in
actions
]
new_action
=
reduce
(
lambda
x
,
y
:
x
|
y
,
new_actions
)
perm
.
action
=
new_action
perm
.
save
()
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'perms'
,
'0005_auto_20190521_1619'
),
]
operations
=
[
migrations
.
AddField
(
model_name
=
'assetpermission'
,
name
=
'action'
,
field
=
models
.
IntegerField
(
choices
=
[(
255
,
'All'
),
(
1
,
'Connect'
),
(
2
,
'Upload file'
),
(
6
,
'Upload download'
),
(
4
,
'Download file'
)],
default
=
255
,
verbose_name
=
'Action'
),
),
migrations
.
RunPython
(
migrate_old_actions
),
]
apps/perms/migrations/0007_auto_20180807_1116.py
deleted
100644 → 0
View file @
48ba1993
# Generated by Django 2.0.7 on 2018-08-07 03:16
from
django.db
import
migrations
,
models
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'perms'
,
'0006_auto_20180606_1505'
),
]
operations
=
[
migrations
.
AddField
(
model_name
=
'assetpermission'
,
name
=
'org_id'
,
field
=
models
.
CharField
(
blank
=
True
,
default
=
None
,
max_length
=
36
,
null
=
True
),
),
migrations
.
AddField
(
model_name
=
'nodepermission'
,
name
=
'org_id'
,
field
=
models
.
CharField
(
blank
=
True
,
default
=
None
,
max_length
=
36
,
null
=
True
),
),
migrations
.
AlterField
(
model_name
=
'assetpermission'
,
name
=
'name'
,
field
=
models
.
CharField
(
max_length
=
128
,
verbose_name
=
'Name'
),
),
migrations
.
AlterUniqueTogether
(
name
=
'assetpermission'
,
unique_together
=
{(
'org_id'
,
'name'
)},
),
migrations
.
AlterUniqueTogether
(
name
=
'nodepermission'
,
unique_together
=
set
(),
),
]
apps/perms/migrations/000
9_auto_20180903_1132
.py
→
apps/perms/migrations/000
7_remove_assetpermission_actions
.py
View file @
8e9b3f13
# Generated by Django 2.1
on 2018-09-03 03:3
2
# Generated by Django 2.1
.7 on 2019-06-28 12:0
2
from
django.db
import
migrations
from
django.db
import
migrations
...
@@ -6,12 +6,12 @@ from django.db import migrations
...
@@ -6,12 +6,12 @@ from django.db import migrations
class
Migration
(
migrations
.
Migration
):
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
dependencies
=
[
(
'perms'
,
'000
8_auto_20180816_1652
'
),
(
'perms'
,
'000
6_auto_20190628_1921
'
),
]
]
operations
=
[
operations
=
[
migrations
.
AlterModelOptions
(
migrations
.
RemoveField
(
name
=
'assetpermission'
,
model_
name
=
'assetpermission'
,
options
=
{
'verbose_name'
:
'Asset permission'
}
,
name
=
'actions'
,
),
),
]
]
apps/perms/migrations/0008_auto_20180816_1652.py
deleted
100644 → 0
View file @
48ba1993
# Generated by Django 2.0.7 on 2018-08-16 08:52
from
django.db
import
migrations
,
models
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'perms'
,
'0007_auto_20180807_1116'
),
]
operations
=
[
migrations
.
AlterField
(
model_name
=
'assetpermission'
,
name
=
'org_id'
,
field
=
models
.
CharField
(
blank
=
True
,
db_index
=
True
,
default
=
''
,
max_length
=
36
,
verbose_name
=
'Organization'
),
),
migrations
.
AlterField
(
model_name
=
'nodepermission'
,
name
=
'org_id'
,
field
=
models
.
CharField
(
blank
=
True
,
db_index
=
True
,
default
=
''
,
max_length
=
36
,
verbose_name
=
'Organization'
),
),
]
apps/perms/models/asset_permission.py
View file @
8e9b3f13
...
@@ -11,7 +11,7 @@ from .base import BasePermission
...
@@ -11,7 +11,7 @@ from .base import BasePermission
__all__
=
[
__all__
=
[
'Action'
,
'AssetPermission'
,
'NodePermission'
,
'Action'
,
'AssetPermission'
,
'NodePermission'
,
'ActionFlag'
]
]
...
@@ -33,11 +33,28 @@ class Action(models.Model):
...
@@ -33,11 +33,28 @@ class Action(models.Model):
return
cls
.
objects
.
get
(
name
=
PERMS_ACTION_NAME_ALL
)
return
cls
.
objects
.
get
(
name
=
PERMS_ACTION_NAME_ALL
)
class
ActionFlag
:
CONNECT
=
0
b00000001
UPLOAD
=
0
b00000010
DOWNLOAD
=
0
b00000100
UPDOWNLOAD
=
CONNECT
|
DOWNLOAD
ALL
=
0
b11111111
CHOICES
=
(
(
ALL
,
_
(
'All'
)),
(
CONNECT
,
_
(
'Connect'
)),
(
UPLOAD
,
_
(
'Upload file'
)),
(
UPDOWNLOAD
,
_
(
"Upload download"
)),
(
DOWNLOAD
,
_
(
'Download file'
)),
)
class
AssetPermission
(
BasePermission
):
class
AssetPermission
(
BasePermission
):
assets
=
models
.
ManyToManyField
(
'assets.Asset'
,
related_name
=
'granted_by_permissions'
,
blank
=
True
,
verbose_name
=
_
(
"Asset"
))
assets
=
models
.
ManyToManyField
(
'assets.Asset'
,
related_name
=
'granted_by_permissions'
,
blank
=
True
,
verbose_name
=
_
(
"Asset"
))
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"
))
class
Meta
:
class
Meta
:
unique_together
=
[(
'org_id'
,
'name'
)]
unique_together
=
[(
'org_id'
,
'name'
)]
...
...
apps/perms/serializers/asset_permission.py
View file @
8e9b3f13
...
@@ -13,16 +13,10 @@ __all__ = [
...
@@ -13,16 +13,10 @@ __all__ = [
'AssetPermissionCreateUpdateSerializer'
,
'AssetPermissionListSerializer'
,
'AssetPermissionCreateUpdateSerializer'
,
'AssetPermissionListSerializer'
,
'AssetPermissionUpdateUserSerializer'
,
'AssetPermissionUpdateAssetSerializer'
,
'AssetPermissionUpdateUserSerializer'
,
'AssetPermissionUpdateAssetSerializer'
,
'AssetPermissionNodeSerializer'
,
'GrantedNodeSerializer'
,
'AssetPermissionNodeSerializer'
,
'GrantedNodeSerializer'
,
'
ActionSerializer'
,
'
NodeGrantedSerializer'
,
'NodeGrantedSerializer'
,
]
]
class
ActionSerializer
(
serializers
.
ModelSerializer
):
class
Meta
:
model
=
Action
fields
=
'__all__'
class
AssetPermissionCreateUpdateSerializer
(
BulkOrgResourceModelSerializer
):
class
AssetPermissionCreateUpdateSerializer
(
BulkOrgResourceModelSerializer
):
class
Meta
:
class
Meta
:
model
=
AssetPermission
model
=
AssetPermission
...
@@ -35,7 +29,7 @@ class AssetPermissionListSerializer(BulkOrgResourceModelSerializer):
...
@@ -35,7 +29,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
s
=
StringManyToManyField
(
many
=
True
,
read_only
=
True
)
action
=
serializers
.
IntegerField
(
read_only
=
True
)
is_valid
=
serializers
.
BooleanField
()
is_valid
=
serializers
.
BooleanField
()
is_expired
=
serializers
.
BooleanField
()
is_expired
=
serializers
.
BooleanField
()
...
...
apps/perms/signals_handler.py
View file @
8e9b3f13
...
@@ -25,13 +25,6 @@ def on_transaction_commit(func):
...
@@ -25,13 +25,6 @@ def on_transaction_commit(func):
@on_transaction_commit
@on_transaction_commit
def
on_permission_created
(
sender
,
instance
=
None
,
created
=
False
,
**
kwargs
):
def
on_permission_created
(
sender
,
instance
=
None
,
created
=
False
,
**
kwargs
):
AssetPermissionUtil
.
expire_all_cache
()
AssetPermissionUtil
.
expire_all_cache
()
actions
=
instance
.
actions
.
all
()
if
created
and
not
actions
:
default_action
=
Action
.
get_action_all
()
instance
.
actions
.
add
(
default_action
)
logger
.
debug
(
"Set default action to perms: {}"
.
format
(
default_action
,
instance
)
)
@receiver
(
post_save
,
sender
=
AssetPermission
)
@receiver
(
post_save
,
sender
=
AssetPermission
)
...
...
apps/perms/templates/perms/asset_permission_create_update.html
View file @
8e9b3f13
...
@@ -48,7 +48,7 @@
...
@@ -48,7 +48,7 @@
{% bootstrap_field form.system_users layout="horizontal" %}
{% bootstrap_field form.system_users layout="horizontal" %}
<div
class=
"hr-line-dashed"
></div>
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'Action' %}
</h3>
<h3>
{% trans 'Action' %}
</h3>
{% bootstrap_field form.action
s
layout="horizontal" %}
{% bootstrap_field form.action layout="horizontal" %}
<div
class=
"hr-line-dashed"
></div>
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'Other' %}
</h3>
<h3>
{% trans 'Other' %}
</h3>
<div
class=
"form-group"
>
<div
class=
"form-group"
>
...
@@ -143,6 +143,34 @@ $(document).ready(function () {
...
@@ -143,6 +143,34 @@ $(document).ready(function () {
$
(
'#id_assets'
).
val
(
assets
).
trigger
(
'change'
);
$
(
'#id_assets'
).
val
(
assets
).
trigger
(
'change'
);
$
(
"#asset_list_modal"
).
modal
(
'hide'
);
$
(
"#asset_list_modal"
).
modal
(
'hide'
);
});
})
.
on
(
"submit"
,
"form"
,
function
(
evt
)
{
evt
.
preventDefault
();
var
the_url
=
'{% url '
api
-
perms
:
asset
-
permission
-
list
' %}'
;
var
redirect_to
=
'{% url "perms:asset-permission-list" %}'
;
var
method
=
"POST"
;
var
form
=
$
(
"form"
);
var
data
=
form
.
serializeObject
();
console
.
log
(
data
)
var
actions
=
data
.
action
;
var
action
=
0
;
for
(
i
=
0
;
i
<
actions
.
length
;
i
++
)
{
console
.
log
(
actions
[
i
])
action
|=
actions
[
i
];
}
data
.
action
=
action
;
objectAttrsIsList
(
data
,
[
'users'
,
'user_groups'
,
'system_users'
,
'nodes'
,
'assets'
]);
objectAttrsIsDatetime
(
data
,
[
'date_start'
,
'date_expired'
]);
objectAttrsIsBool
(
data
,
[
'is_active'
])
console
.
log
(
data
)
var
props
=
{
url
:
the_url
,
data
:
data
,
method
:
method
,
form
:
form
,
redirect_to
:
redirect_to
};
formSubmit
(
props
);
})
</script>
</script>
{% endblock %}
{% endblock %}
\ No newline at end of file
apps/perms/templates/perms/asset_permission_list.html
View file @
8e9b3f13
...
@@ -24,15 +24,7 @@
...
@@ -24,15 +24,7 @@
<div
class=
"wrapper wrapper-content"
>
<div
class=
"wrapper wrapper-content"
>
<div
class=
"row"
>
<div
class=
"row"
>
<div
class=
"col-lg-3"
id=
"split-left"
style=
"padding-left: 3px"
>
<div
class=
"col-lg-3"
id=
"split-left"
style=
"padding-left: 3px"
>
<div
class=
"ibox float-e-margins"
>
{% include 'assets/_node_tree.html' %}
<div
class=
"ibox-content mailbox-content"
style=
"padding-top: 0;padding-left: 1px"
>
<div
class=
"file-manager "
>
<div
id=
"assetTree"
class=
"ztree"
>
</div>
<div
class=
"clearfix"
></div>
</div>
</div>
</div>
</div>
</div>
<div
class=
"col-lg-9 animated fadeInRight"
id=
"split-right"
>
<div
class=
"col-lg-9 animated fadeInRight"
id=
"split-right"
>
<div
class=
"tree-toggle"
>
<div
class=
"tree-toggle"
>
...
@@ -86,7 +78,7 @@
...
@@ -86,7 +78,7 @@
<script>
<script>
var
zTree
,
table
,
show
=
0
;
var
zTree
,
table
,
show
=
0
;
function
onSelected
(
event
,
treeNode
)
{
function
on
Node
Selected
(
event
,
treeNode
)
{
setCookie
(
'node_selected'
,
treeNode
.
id
);
setCookie
(
'node_selected'
,
treeNode
.
id
);
var
url
=
table
.
ajax
.
url
();
var
url
=
table
.
ajax
.
url
();
if
(
treeNode
.
meta
.
type
===
'node'
)
{
if
(
treeNode
.
meta
.
type
===
'node'
)
{
...
@@ -102,7 +94,7 @@ function onSelected(event, treeNode) {
...
@@ -102,7 +94,7 @@ function onSelected(event, treeNode) {
}
}
function
beforeAsync
(
treeId
,
treeNode
)
{
function
before
Node
Async
(
treeId
,
treeNode
)
{
if
(
treeNode
)
{
if
(
treeNode
)
{
return
treeNode
.
meta
.
type
===
'node'
return
treeNode
.
meta
.
type
===
'node'
}
}
...
@@ -204,28 +196,12 @@ function initTable() {
...
@@ -204,28 +196,12 @@ function initTable() {
function
initTree
()
{
function
initTree
()
{
var
setting
=
{
initNodeTree
({
view
:
{
onSelected
:
onNodeSelected
,
dblClickExpand
:
false
,
beforeAsync
:
beforeNodeAsync
,
showLine
:
true
showMenu
:
false
,
},
showAssets
:
true
,
data
:
{
})
simpleData
:
{
enable
:
true
}
},
async
:
{
enable
:
true
,
url
:
"{% url 'api-assets:node-children-tree' %}?assets=1"
,
autoParam
:[
"id=key"
,
"name=n"
,
"level=lv"
],
type
:
'get'
},
callback
:
{
onSelected
:
onSelected
,
beforeAsync
:
beforeAsync
}
};
zTree
=
$
.
fn
.
zTree
.
init
(
$
(
"#assetTree"
),
setting
);
}
}
function
toggle
()
{
function
toggle
()
{
...
...
apps/perms/urls/api_urls.py
View file @
8e9b3f13
...
@@ -7,7 +7,6 @@ from .. import api
...
@@ -7,7 +7,6 @@ from .. import api
app_name
=
'perms'
app_name
=
'perms'
router
=
routers
.
DefaultRouter
()
router
=
routers
.
DefaultRouter
()
router
.
register
(
'actions'
,
api
.
ActionViewSet
,
'action'
)
router
.
register
(
'asset-permissions'
,
api
.
AssetPermissionViewSet
,
'asset-permission'
)
router
.
register
(
'asset-permissions'
,
api
.
AssetPermissionViewSet
,
'asset-permission'
)
router
.
register
(
'remote-app-permissions'
,
api
.
RemoteAppPermissionViewSet
,
'remote-app-permission'
)
router
.
register
(
'remote-app-permissions'
,
api
.
RemoteAppPermissionViewSet
,
'remote-app-permission'
)
...
...
apps/perms/utils/asset_permission.py
View file @
8e9b3f13
...
@@ -5,6 +5,7 @@ from collections import defaultdict
...
@@ -5,6 +5,7 @@ from collections import defaultdict
import
json
import
json
from
hashlib
import
md5
from
hashlib
import
md5
import
time
import
time
import
itertools
from
django.utils
import
timezone
from
django.utils
import
timezone
from
django.db.models
import
Q
from
django.db.models
import
Q
...
@@ -102,11 +103,11 @@ def get_user_permissions(user, include_group=True):
...
@@ -102,11 +103,11 @@ def get_user_permissions(user, include_group=True):
arg
=
Q
(
users
=
user
)
|
Q
(
user_groups__in
=
groups
)
arg
=
Q
(
users
=
user
)
|
Q
(
user_groups__in
=
groups
)
else
:
else
:
arg
=
Q
(
users
=
user
)
arg
=
Q
(
users
=
user
)
return
AssetPermission
.
objects
.
all
()
.
valid
()
.
filter
(
arg
)
return
AssetPermission
.
objects
.
valid
()
.
filter
(
arg
)
def
get_user_group_permissions
(
user_group
):
def
get_user_group_permissions
(
user_group
):
return
AssetPermission
.
objects
.
all
()
.
valid
()
.
filter
(
return
AssetPermission
.
objects
.
valid
()
.
filter
(
user_groups
=
user_group
user_groups
=
user_group
)
)
...
@@ -117,15 +118,15 @@ def get_asset_permissions(asset, include_node=True):
...
@@ -117,15 +118,15 @@ def get_asset_permissions(asset, include_node=True):
arg
=
Q
(
assets
=
asset
)
|
Q
(
nodes__in
=
nodes
)
arg
=
Q
(
assets
=
asset
)
|
Q
(
nodes__in
=
nodes
)
else
:
else
:
arg
=
Q
(
assets
=
asset
)
arg
=
Q
(
assets
=
asset
)
return
AssetPermission
.
objects
.
all
()
.
valid
()
.
filter
(
arg
)
return
AssetPermission
.
objects
.
valid
()
.
filter
(
arg
)
def
get_node_permissions
(
node
):
def
get_node_permissions
(
node
):
return
AssetPermission
.
objects
.
all
()
.
valid
()
.
filter
(
nodes
=
node
)
return
AssetPermission
.
objects
.
valid
()
.
filter
(
nodes
=
node
)
def
get_system_user_permissions
(
system_user
):
def
get_system_user_permissions
(
system_user
):
return
AssetPermission
.
objects
.
valid
()
.
all
()
.
filter
(
return
AssetPermission
.
objects
.
valid
()
.
filter
(
system_users
=
system_user
system_users
=
system_user
)
)
...
@@ -141,11 +142,6 @@ def timeit(func):
...
@@ -141,11 +142,6 @@ def timeit(func):
return
wrapper
return
wrapper
class
AssetGranted
:
def
__init__
(
self
):
self
.
system_users
=
{}
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_'
...
@@ -286,6 +282,38 @@ class AssetPermissionCacheMixin:
...
@@ -286,6 +282,38 @@ class AssetPermissionCacheMixin:
cache
.
delete_pattern
(
key
)
cache
.
delete_pattern
(
key
)
class
FlatPermissionQueryset
:
def
__init__
(
self
):
self
.
queryset
=
defaultdict
(
list
)
def
add
(
self
,
permission
):
self
.
queryset
[
permission
.
id
]
.
append
(
permission
)
def
add_many
(
self
,
assets_or_nodes
,
system_users
,
actions
):
if
any
([
assets_or_nodes
,
system_users
,
actions
]):
return
iterable
=
itertools
.
product
(
assets_or_nodes
,
system_users
,
actions
)
for
source
,
sysuser
,
action
in
iterable
:
permission
=
FlatPermission
(
source
,
sysuser
,
action
)
self
.
add
(
permission
)
def
clean
(
self
):
pass
class
FlatPermission
:
def
__init__
(
self
,
asset_or_node
,
system_user
,
action
):
self
.
id
=
asset_or_node
.
id
self
.
source
=
asset_or_node
self
.
system_user
=
system_user
self
.
action
=
action
def
__eq__
(
self
,
other
):
pass
class
AssetPermissionUtil
(
AssetPermissionCacheMixin
):
class
AssetPermissionUtil
(
AssetPermissionCacheMixin
):
get_permissions_map
=
{
get_permissions_map
=
{
"User"
:
get_user_permissions
,
"User"
:
get_user_permissions
,
...
@@ -344,19 +372,15 @@ class AssetPermissionUtil(AssetPermissionCacheMixin):
...
@@ -344,19 +372,15 @@ class AssetPermissionUtil(AssetPermissionCacheMixin):
def
get_nodes_direct
(
self
):
def
get_nodes_direct
(
self
):
"""
"""
返回用户/组授权规则直接关联的节点
返回用户/组授权规则直接关联的节点
:return: {
asset
1: {system_user1: {'actions': set()},}}
:return: {
node
1: {system_user1: {'actions': set()},}}
"""
"""
nodes
=
defaultdict
(
dict
)
nodes
=
FlatPermissionQueryset
(
)
permissions
=
self
.
permissions
.
prefetch_related
(
'nodes'
,
'system_users'
,
'actions'
)
permissions
=
self
.
permissions
for
perm
in
permissions
:
for
perm
in
permissions
:
actions
=
perm
.
actions
.
all
()
actions
=
perm
.
actions
.
all
()
for
node
in
perm
.
nodes
.
all
():
system_users
=
perm
.
system_users
.
all
()
system_users
=
perm
.
system_users
.
all
()
_nodes
=
perm
.
nodes
.
all
()
system_users
=
self
.
_structured_system_user
(
system_users
,
actions
)
nodes
.
add_many
(
_nodes
,
system_users
,
actions
)
nodes
[
node
]
.
update
(
system_users
)
self
.
tree
.
add_nodes
(
nodes
.
keys
())
# 替换成优化过的node
nodes
=
{
self
.
tree
.
node_util
.
get_node_by_key
(
k
.
key
):
v
for
k
,
v
in
nodes
.
items
()}
return
nodes
return
nodes
@timeit
@timeit
...
@@ -385,24 +409,18 @@ class AssetPermissionUtil(AssetPermissionCacheMixin):
...
@@ -385,24 +409,18 @@ class AssetPermissionUtil(AssetPermissionCacheMixin):
assets
=
self
.
get_assets_direct
()
assets
=
self
.
get_assets_direct
()
nodes
=
self
.
get_nodes_direct
()
nodes
=
self
.
get_nodes_direct
()
# for node, system_users in nodes.items():
# for node, system_users in nodes.items():
# print(9999, node)
# print(">>>>> Node<<<<<<<<<<<<: ", node.value)
# _assets = node.get_all_valid_assets()
# _assets = list(node.get_all_valid_assets())
# print(".......... end .......")
# for asset in _assets:
# for asset in _assets:
# print(">>asset")
# for system_user, attr_dict in system_users.items():
# for system_user, attr_dict in system_users.items():
# print(">>>system user")
# if not asset.has_protocol(system_user.protocol):
# if not asset.has_protocol(system_user.protocol):
# continue
# continue
# if system_user in assets[asset]:
# if system_user in assets[asset]:
# actions = assets[asset][system_user]['actions']
# actions = assets[asset][system_user]['actions']
# attr_dict['actions'].update(actions)
# attr_dict['actions'].update(actions)
# system_users.update({system_user: attr_dict})
# system_users.update({system_user: attr_dict})
# print("<<<system user")
# print("<<<asset")
# assets[asset].update(system_users)
# assets[asset].update(system_users)
# print(">>>>>>")
#
__assets
=
defaultdict
(
set
)
__assets
=
defaultdict
(
set
)
for
asset
,
system_users
in
assets
.
items
():
for
asset
,
system_users
in
assets
.
items
():
for
system_user
,
attr_dict
in
system_users
.
items
():
for
system_user
,
attr_dict
in
system_users
.
items
():
...
@@ -507,8 +525,7 @@ def parse_asset_to_tree_node(node, asset, system_users):
...
@@ -507,8 +525,7 @@ def parse_asset_to_tree_node(node, asset, system_users):
'id'
:
asset
.
id
,
'id'
:
asset
.
id
,
'hostname'
:
asset
.
hostname
,
'hostname'
:
asset
.
hostname
,
'ip'
:
asset
.
ip
,
'ip'
:
asset
.
ip
,
'protocols'
:
[{
"name"
:
p
.
name
,
"port"
:
p
.
port
}
'protocols'
:
[
str
(
p
)
for
p
in
asset
.
protocols
.
all
()],
for
p
in
asset
.
protocols
.
all
()],
'platform'
:
asset
.
platform
,
'platform'
:
asset
.
platform
,
'domain'
:
None
if
not
asset
.
domain
else
asset
.
domain
.
id
,
'domain'
:
None
if
not
asset
.
domain
else
asset
.
domain
.
id
,
'is_active'
:
asset
.
is_active
,
'is_active'
:
asset
.
is_active
,
...
...
apps/perms/views/asset_permission.py
View file @
8e9b3f13
...
@@ -58,8 +58,6 @@ class AssetPermissionCreateView(PermissionsMixin, CreateView):
...
@@ -58,8 +58,6 @@ class AssetPermissionCreateView(PermissionsMixin, CreateView):
assets_id
=
assets_id
.
split
(
","
)
assets_id
=
assets_id
.
split
(
","
)
assets
=
Asset
.
objects
.
filter
(
id__in
=
assets_id
)
assets
=
Asset
.
objects
.
filter
(
id__in
=
assets_id
)
form
[
'assets'
]
.
initial
=
assets
form
[
'assets'
]
.
initial
=
assets
form
[
'actions'
]
.
initial
=
Action
.
objects
.
get
(
name
=
PERMS_ACTION_NAME_ALL
)
return
form
return
form
def
get_context_data
(
self
,
**
kwargs
):
def
get_context_data
(
self
,
**
kwargs
):
...
...
apps/static/js/jumpserver.js
View file @
8e9b3f13
...
@@ -277,7 +277,7 @@ function APIUpdateAttr(props) {
...
@@ -277,7 +277,7 @@ function APIUpdateAttr(props) {
}).
done
(
function
(
data
,
textStatue
,
jqXHR
)
{
}).
done
(
function
(
data
,
textStatue
,
jqXHR
)
{
if
(
flash_message
)
{
if
(
flash_message
)
{
var
msg
=
""
;
var
msg
=
""
;
if
(
user_
fail
_message
)
{
if
(
user_
success
_message
)
{
msg
=
user_success_message
;
msg
=
user_success_message
;
}
else
{
}
else
{
msg
=
default_success_message
;
msg
=
default_success_message
;
...
@@ -635,7 +635,7 @@ jumpserver.initServerSideDataTable = function (options) {
...
@@ -635,7 +635,7 @@ jumpserver.initServerSideDataTable = function (options) {
columns
:
options
.
columns
||
[],
columns
:
options
.
columns
||
[],
select
:
options
.
select
||
select
,
select
:
options
.
select
||
select
,
language
:
jumpserver
.
language
,
language
:
jumpserver
.
language
,
lengthMenu
:
[[
15
,
25
,
50
,
9999
],
[
15
,
25
,
50
,
'All'
]]
lengthMenu
:
options
.
lengthMenu
||
[[
15
,
25
,
50
,
9999
],
[
15
,
25
,
50
,
'All'
]]
});
});
table
.
selected
=
[];
table
.
selected
=
[];
table
.
selected_rows
=
[];
table
.
selected_rows
=
[];
...
@@ -1072,3 +1072,27 @@ function htmlEscape ( d ) {
...
@@ -1072,3 +1072,27 @@ function htmlEscape ( d ) {
d
.
replace
(
/</g
,
'<'
).
replace
(
/>/g
,
'>'
).
replace
(
/"/g
,
'"'
)
:
d
.
replace
(
/</g
,
'<'
).
replace
(
/>/g
,
'>'
).
replace
(
/"/g
,
'"'
)
:
d
;
d
;
}
}
function
objectAttrsIsList
(
obj
,
attrs
)
{
attrs
.
forEach
(
function
(
attr
)
{
if
(
obj
[
attr
]
&&
!
(
obj
[
attr
]
instanceof
Array
)){
obj
[
attr
]
=
[
obj
[
attr
]]
}
})
}
function
objectAttrsIsDatetime
(
obj
,
attrs
)
{
attrs
.
forEach
(
function
(
attr
)
{
obj
[
attr
]
=
new
Date
(
obj
[
attr
]).
toISOString
();
})
}
function
objectAttrsIsBool
(
obj
,
attrs
)
{
attrs
.
forEach
(
function
(
attr
)
{
if
(
!
obj
[
attr
])
{
obj
[
attr
]
=
false
}
else
if
([
'on'
,
'1'
].
includes
(
obj
[
attr
]))
{
obj
[
attr
]
=
true
}
})
}
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