[Feature] 更改perms api

pull/1043/head
ibuler 2018-02-07 23:25:15 +08:00
parent 6104acae8f
commit 3bb6e08985
22 changed files with 649 additions and 806 deletions

View File

@ -1,7 +1,5 @@
from .admin_user import * from .admin_user import *
from .asset import * from .asset import *
from .cluster import *
from .group import *
from .label import * from .label import *
from .system_user import * from .system_user import *
from .tree import * from .node import *

View File

@ -12,7 +12,7 @@ from django.db.models import Q
from common.mixins import IDInFilterMixin from common.mixins import IDInFilterMixin
from common.utils import get_logger from common.utils import get_logger
from ..hands import IsSuperUser, IsValidUser, IsSuperUserOrAppUser, \ from ..hands import IsSuperUser, IsValidUser, IsSuperUserOrAppUser, \
get_user_granted_assets NodePermissionUtil
from ..models import Asset, SystemUser, AdminUser, Node from ..models import Asset, SystemUser, AdminUser, Node
from .. import serializers from .. import serializers
from ..tasks import update_asset_hardware_info_manual, \ from ..tasks import update_asset_hardware_info_manual, \
@ -41,16 +41,10 @@ class AssetViewSet(IDInFilterMixin, LabelFilter, BulkModelViewSet):
def get_queryset(self): def get_queryset(self):
queryset = super().get_queryset() queryset = super().get_queryset()
cluster_id = self.request.query_params.get('cluster_id')
asset_group_id = self.request.query_params.get('asset_group_id')
admin_user_id = self.request.query_params.get('admin_user_id') admin_user_id = self.request.query_params.get('admin_user_id')
system_user_id = self.request.query_params.get('system_user_id') system_user_id = self.request.query_params.get('system_user_id')
node_id = self.request.query_params.get("node_id") node_id = self.request.query_params.get("node_id")
if cluster_id:
queryset = queryset.filter(cluster__id=cluster_id)
if asset_group_id:
queryset = queryset.filter(groups__id=asset_group_id)
if admin_user_id: if admin_user_id:
admin_user = get_object_or_404(AdminUser, id=admin_user_id) admin_user = get_object_or_404(AdminUser, id=admin_user_id)
assets_direct = [asset.id for asset in admin_user.asset_set.all()] assets_direct = [asset.id for asset in admin_user.asset_set.all()]
@ -72,7 +66,7 @@ class UserAssetListView(generics.ListAPIView):
permission_classes = (IsValidUser,) permission_classes = (IsValidUser,)
def get_queryset(self): def get_queryset(self):
assets_granted = get_user_granted_assets(self.request.user) assets_granted = NodePermissionUtil.get_user_assets(self.request.user).keys()
queryset = self.queryset.filter( queryset = self.queryset.filter(
id__in=[asset.id for asset in assets_granted] id__in=[asset.id for asset in assets_granted]
) )

View File

@ -14,5 +14,5 @@
from users.utils import AdminUserRequiredMixin from users.utils import AdminUserRequiredMixin
from users.permissions import IsAppUser, IsSuperUser, IsValidUser, IsSuperUserOrAppUser from users.permissions import IsAppUser, IsSuperUser, IsValidUser, IsSuperUserOrAppUser
from users.models import User, UserGroup from users.models import User, UserGroup
from perms.utils import get_user_granted_assets from perms.utils import NodePermissionUtil
from perms.tasks import push_users from perms.tasks import push_users

View File

@ -47,16 +47,20 @@ class Node(models.Model):
def get_all_children(self): def get_all_children(self):
return self.__class__.objects.filter(key__startswith='{}:'.format(self.key)) return self.__class__.objects.filter(key__startswith='{}:'.format(self.key))
def get_family(self):
children = list(self.get_all_children())
children.append(self)
return children
def get_assets(self): def get_assets(self):
from .asset import Asset from .asset import Asset
children = self.get_children() assets = Asset.objects.filter(nodes__id=self.id)
assets = Asset.objects.filter(nodes__in=children)
return assets return assets
def get_all_assets(self): def get_all_assets(self):
from .asset import Asset from .asset import Asset
children = self.get_all_children() nodes = self.get_family()
assets = Asset.objects.filter(nodes__in=children) assets = Asset.objects.filter(nodes__in=nodes)
return assets return assets
@property @property

View File

@ -1,345 +0,0 @@
# -*- coding: utf-8 -*-
from django.core.cache import cache
from rest_framework import serializers
from rest_framework_bulk.serializers import BulkListSerializer
from common.mixins import BulkSerializerMixin
from .models import AssetGroup, Asset, Cluster, AdminUser, SystemUser, Label, Node
from .const import ADMIN_USER_CONN_CACHE_KEY
class AssetGroupSerializer(BulkSerializerMixin, serializers.ModelSerializer):
"""
资产组序列化数据模型
"""
assets_display = serializers.SerializerMethodField()
assets = serializers.PrimaryKeyRelatedField(
many=True, queryset=Asset.objects.all(), required=False
)
class Meta:
model = AssetGroup
list_serializer_class = BulkListSerializer
fields = ['id', 'name', 'comment', 'assets_display', 'assets']
@staticmethod
def get_assets_display(obj):
return [asset.hostname for asset in obj.assets.all()]
class AssetUpdateSystemUserSerializer(serializers.ModelSerializer):
"""
资产更新其系统用户请求的数据结构定义
"""
system_users = serializers.PrimaryKeyRelatedField(many=True, queryset=SystemUser.objects.all())
class Meta:
model = Asset
fields = ['id', 'system_users']
class GroupUpdateAssetsSerializer(serializers.ModelSerializer):
"""
资产组更新需要的数据结构
"""
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
class Meta:
model = AssetGroup
fields = ['id', 'assets']
class ClusterUpdateAssetsSerializer(serializers.ModelSerializer):
"""
集群更新资产数据结构
"""
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
class Meta:
model = Cluster
fields = ['id', 'assets']
class AdminUserSerializer(serializers.ModelSerializer):
"""
管理用户
"""
assets_amount = serializers.SerializerMethodField()
unreachable_amount = serializers.SerializerMethodField()
reachable_amount = serializers.SerializerMethodField()
class Meta:
model = AdminUser
fields = '__all__'
@staticmethod
def get_unreachable_amount(obj):
data = cache.get(ADMIN_USER_CONN_CACHE_KEY.format(obj.name))
if data:
return len(data.get('dark'))
else:
return 0
@staticmethod
def get_reachable_amount(obj):
data = cache.get(ADMIN_USER_CONN_CACHE_KEY.format(obj.name))
if data:
return len(data.get('contacted'))
else:
return 0
@staticmethod
def get_assets_amount(obj):
return obj.assets_amount
class SystemUserSerializer(serializers.ModelSerializer):
"""
系统用户
"""
unreachable_amount = serializers.SerializerMethodField()
reachable_amount = serializers.SerializerMethodField()
unreachable_assets = serializers.SerializerMethodField()
reachable_assets = serializers.SerializerMethodField()
assets_amount = serializers.SerializerMethodField()
class Meta:
model = SystemUser
exclude = ('_password', '_private_key', '_public_key')
@staticmethod
def get_unreachable_assets(obj):
return obj.unreachable_assets
@staticmethod
def get_reachable_assets(obj):
return obj.reachable_assets
def get_unreachable_amount(self, obj):
return len(self.get_unreachable_assets(obj))
def get_reachable_amount(self, obj):
return len(self.get_reachable_assets(obj))
@staticmethod
def get_assets_amount(obj):
amount = 0
for cluster in obj.cluster.all():
amount += cluster.assets.all().count()
return amount
class AdminUserUpdateClusterSerializer(serializers.ModelSerializer):
"""
管理用户更新关联到的集群
"""
clusters = serializers.PrimaryKeyRelatedField(many=True, queryset=Cluster.objects.all())
class Meta:
model = AdminUser
fields = ['id', 'clusters']
class AssetSystemUserSerializer(serializers.ModelSerializer):
"""
查看授权的资产系统用户的数据结构这个和AssetSerializer不同字段少
"""
class Meta:
model = SystemUser
fields = ('id', 'name', 'username', 'priority', 'protocol', 'comment',)
class SystemUserSimpleSerializer(serializers.ModelSerializer):
"""
系统用户最基本信息的数据结构
"""
class Meta:
model = SystemUser
fields = ('id', 'name', 'username')
class AssetSerializer(BulkSerializerMixin, serializers.ModelSerializer):
"""
资产的数据结构
"""
cluster_name = serializers.SerializerMethodField()
class Meta(object):
model = Asset
list_serializer_class = BulkListSerializer
fields = '__all__'
validators = [] # If not set to [], partial bulk update will be error
def get_field_names(self, declared_fields, info):
fields = super().get_field_names(declared_fields, info)
fields.extend([
'hardware_info', 'is_connective',
])
return fields
@staticmethod
def get_cluster_name(obj):
return obj.cluster.name
class AssetGrantedSerializer(serializers.ModelSerializer):
"""
被授权资产的数据结构
"""
system_users_granted = AssetSystemUserSerializer(many=True, read_only=True)
is_inherited = serializers.SerializerMethodField()
system_users_join = serializers.SerializerMethodField()
class Meta(object):
model = Asset
fields = (
"id", "hostname", "ip", "port", "system_users_granted",
"is_inherited", "is_active", "system_users_join", "os",
"platform", "comment"
)
@staticmethod
def get_is_inherited(obj):
if getattr(obj, 'inherited', ''):
return True
else:
return False
@staticmethod
def get_system_users_join(obj):
return ', '.join([system_user.username for system_user in obj.system_users_granted])
class MyAssetGrantedSerializer(AssetGrantedSerializer):
"""
普通用户获取授权的资产定义的数据结构
"""
class Meta(object):
model = Asset
fields = (
"id", "hostname", "system_users_granted",
"is_inherited", "is_active", "system_users_join",
"os", "platform", "comment",
)
class ClusterSerializer(BulkSerializerMixin, serializers.ModelSerializer):
"""
cluster
"""
assets_amount = serializers.SerializerMethodField()
admin_user_name = serializers.SerializerMethodField()
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
system_users = serializers.SerializerMethodField()
class Meta:
model = Cluster
fields = '__all__'
@staticmethod
def get_assets_amount(obj):
return obj.assets.count()
@staticmethod
def get_admin_user_name(obj):
try:
return obj.admin_user.name
except AttributeError:
return ''
@staticmethod
def get_system_users(obj):
return ', '.join(obj.name for obj in obj.systemuser_set.all())
class AssetGroupGrantedSerializer(BulkSerializerMixin, serializers.ModelSerializer):
"""
授权资产组
"""
assets_granted = AssetGrantedSerializer(many=True, read_only=True)
assets_amount = serializers.SerializerMethodField()
class Meta:
model = AssetGroup
list_serializer_class = BulkListSerializer
fields = '__all__'
@staticmethod
def get_assets_amount(obj):
return len(obj.assets_granted)
class MyAssetGroupGrantedSerializer(serializers.ModelSerializer):
"""
普通用户授权资产组结构
"""
assets_granted = MyAssetGrantedSerializer(many=True, read_only=True)
assets_amount = serializers.SerializerMethodField()
class Meta:
model = AssetGroup
list_serializer_class = BulkListSerializer
fields = '__all__'
@staticmethod
def get_assets_amount(obj):
return len(obj.assets_granted)
class LabelSerializer(serializers.ModelSerializer):
asset_count = serializers.SerializerMethodField()
class Meta:
model = Label
fields = '__all__'
list_serializer_class = BulkListSerializer
@staticmethod
def get_asset_count(obj):
return obj.assets.count()
def get_field_names(self, declared_fields, info):
fields = super().get_field_names(declared_fields, info)
fields.extend(['get_category_display'])
return fields
class LabelDistinctSerializer(serializers.ModelSerializer):
value = serializers.SerializerMethodField()
class Meta:
model = Label
fields = ("name", "value")
@staticmethod
def get_value(obj):
labels = Label.objects.filter(name=obj["name"])
return ', '.join([label.value for label in labels])
class NodeSerializer(serializers.ModelSerializer):
parent = serializers.SerializerMethodField()
class Meta:
model = Node
fields = ['id', 'key', 'value', 'parent']
list_serializer_class = BulkListSerializer
@staticmethod
def get_parent(obj):
return obj.parent.id
def get_fields(self):
fields = super().get_fields()
field = fields["key"]
field.required = False
return fields
class NodeAssetsSerializer(serializers.ModelSerializer):
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
class Meta:
model = Node
fields = ['assets']

View File

@ -0,0 +1,8 @@
# -*- coding: utf-8 -*-
#
from .asset import *
from .admin_user import *
from .label import *
from .system_user import *
from .node import *

View File

@ -0,0 +1,52 @@
# -*- coding: utf-8 -*-
#
from django.core.cache import cache
from rest_framework import serializers
from ..models import Cluster, AdminUser
from ..const import ADMIN_USER_CONN_CACHE_KEY
class AdminUserSerializer(serializers.ModelSerializer):
"""
管理用户
"""
assets_amount = serializers.SerializerMethodField()
unreachable_amount = serializers.SerializerMethodField()
reachable_amount = serializers.SerializerMethodField()
class Meta:
model = AdminUser
fields = '__all__'
@staticmethod
def get_unreachable_amount(obj):
data = cache.get(ADMIN_USER_CONN_CACHE_KEY.format(obj.name))
if data:
return len(data.get('dark'))
else:
return 0
@staticmethod
def get_reachable_amount(obj):
data = cache.get(ADMIN_USER_CONN_CACHE_KEY.format(obj.name))
if data:
return len(data.get('contacted'))
else:
return 0
@staticmethod
def get_assets_amount(obj):
return obj.assets_amount
class AdminUserUpdateClusterSerializer(serializers.ModelSerializer):
"""
管理用户更新关联到的集群
"""
clusters = serializers.PrimaryKeyRelatedField(
many=True, queryset=Cluster.objects.all()
)
class Meta:
model = AdminUser
fields = ['id', 'clusters']

View File

@ -0,0 +1,67 @@
# -*- coding: utf-8 -*-
#
from rest_framework import serializers
from rest_framework_bulk.serializers import BulkListSerializer
from common.mixins import BulkSerializerMixin
from ..models import Asset
from .system_user import AssetSystemUserSerializer
class AssetSerializer(BulkSerializerMixin, serializers.ModelSerializer):
"""
资产的数据结构
"""
cluster_name = serializers.SerializerMethodField()
class Meta:
model = Asset
list_serializer_class = BulkListSerializer
fields = '__all__'
validators = [] # If not set to [], partial bulk update will be error
def get_field_names(self, declared_fields, info):
fields = super().get_field_names(declared_fields, info)
fields.extend([
'hardware_info', 'is_connective',
])
return fields
@staticmethod
def get_cluster_name(obj):
return obj.cluster.name
class AssetGrantedSerializer(serializers.ModelSerializer):
"""
被授权资产的数据结构
"""
system_users_granted = AssetSystemUserSerializer(many=True, read_only=True)
system_users_join = serializers.SerializerMethodField()
class Meta:
model = Asset
fields = (
"id", "hostname", "ip", "port", "system_users_granted",
"is_active", "system_users_join", "os",
"platform", "comment"
)
@staticmethod
def get_system_users_join(obj):
system_users = [s.username for s in obj.system_users_granted]
return ', '.join(system_users)
class MyAssetGrantedSerializer(AssetGrantedSerializer):
"""
普通用户获取授权的资产定义的数据结构
"""
class Meta:
model = Asset
fields = (
"id", "hostname", "system_users_granted",
"is_active", "system_users_join",
"os", "platform", "comment",
)

View File

@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
#
from rest_framework import serializers
from common.mixins import BulkSerializerMixin
from ..models import Asset, Cluster
class ClusterUpdateAssetsSerializer(serializers.ModelSerializer):
"""
集群更新资产数据结构
"""
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
class Meta:
model = Cluster
fields = ['id', 'assets']
class ClusterSerializer(BulkSerializerMixin, serializers.ModelSerializer):
"""
cluster
"""
assets_amount = serializers.SerializerMethodField()
admin_user_name = serializers.SerializerMethodField()
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
system_users = serializers.SerializerMethodField()
class Meta:
model = Cluster
fields = '__all__'
@staticmethod
def get_assets_amount(obj):
return obj.assets.count()
@staticmethod
def get_admin_user_name(obj):
try:
return obj.admin_user.name
except AttributeError:
return ''
@staticmethod
def get_system_users(obj):
return ', '.join(obj.name for obj in obj.systemuser_set.all())

View File

@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
#
from rest_framework import serializers
from rest_framework_bulk.serializers import BulkListSerializer
from ..models import Label
class LabelSerializer(serializers.ModelSerializer):
asset_count = serializers.SerializerMethodField()
class Meta:
model = Label
fields = '__all__'
list_serializer_class = BulkListSerializer
@staticmethod
def get_asset_count(obj):
return obj.assets.count()
def get_field_names(self, declared_fields, info):
fields = super().get_field_names(declared_fields, info)
fields.extend(['get_category_display'])
return fields
class LabelDistinctSerializer(serializers.ModelSerializer):
value = serializers.SerializerMethodField()
class Meta:
model = Label
fields = ("name", "value")
@staticmethod
def get_value(obj):
labels = Label.objects.filter(name=obj["name"])
return ', '.join([label.value for label in labels])

View File

@ -0,0 +1,58 @@
# -*- coding: utf-8 -*-
from rest_framework import serializers
from rest_framework_bulk.serializers import BulkListSerializer
from common.mixins import BulkSerializerMixin
from ..models import Asset, Node
from .asset import AssetGrantedSerializer
class NodeGrantedSerializer(BulkSerializerMixin, serializers.ModelSerializer):
"""
授权资产组
"""
assets_granted = AssetGrantedSerializer(many=True, read_only=True)
assets_amount = serializers.SerializerMethodField()
parent = serializers.SerializerMethodField()
class Meta:
model = Node
fields = [
'id', 'key', 'value', 'parent',
'assets_granted', 'assets_amount',
]
@staticmethod
def get_assets_amount(obj):
return len(obj.assets_granted)
@staticmethod
def get_parent(obj):
return obj.parent.id
class NodeSerializer(serializers.ModelSerializer):
parent = serializers.SerializerMethodField()
class Meta:
model = Node
fields = ['id', 'key', 'value', 'parent']
list_serializer_class = BulkListSerializer
@staticmethod
def get_parent(obj):
return obj.parent.id
def get_fields(self):
fields = super().get_fields()
field = fields["key"]
field.required = False
return fields
class NodeAssetsSerializer(serializers.ModelSerializer):
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
class Meta:
model = Node
fields = ['assets']

View File

@ -0,0 +1,57 @@
from rest_framework import serializers
from ..models import SystemUser
class SystemUserSerializer(serializers.ModelSerializer):
"""
系统用户
"""
unreachable_amount = serializers.SerializerMethodField()
reachable_amount = serializers.SerializerMethodField()
unreachable_assets = serializers.SerializerMethodField()
reachable_assets = serializers.SerializerMethodField()
assets_amount = serializers.SerializerMethodField()
class Meta:
model = SystemUser
exclude = ('_password', '_private_key', '_public_key')
@staticmethod
def get_unreachable_assets(obj):
return obj.unreachable_assets
@staticmethod
def get_reachable_assets(obj):
return obj.reachable_assets
def get_unreachable_amount(self, obj):
return len(self.get_unreachable_assets(obj))
def get_reachable_amount(self, obj):
return len(self.get_reachable_assets(obj))
@staticmethod
def get_assets_amount(obj):
amount = 0
for cluster in obj.cluster.all():
amount += cluster.assets.all().count()
return amount
class AssetSystemUserSerializer(serializers.ModelSerializer):
"""
查看授权的资产系统用户的数据结构这个和AssetSerializer不同字段少
"""
class Meta:
model = SystemUser
fields = ('id', 'name', 'username', 'priority', 'protocol', 'comment',)
class SystemUserSimpleSerializer(serializers.ModelSerializer):
"""
系统用户最基本信息的数据结构
"""
class Meta:
model = SystemUser
fields = ('id', 'name', 'username')

View File

@ -7,9 +7,9 @@ app_name = 'assets'
router = BulkRouter() router = BulkRouter()
router.register(r'v1/groups', api.AssetGroupViewSet, 'asset-group') # router.register(r'v1/groups', api.AssetGroupViewSet, 'asset-group')
router.register(r'v1/assets', api.AssetViewSet, 'asset') router.register(r'v1/assets', api.AssetViewSet, 'asset')
router.register(r'v1/clusters', api.ClusterViewSet, 'cluster') # router.register(r'v1/clusters', api.ClusterViewSet, 'cluster')
router.register(r'v1/admin-user', api.AdminUserViewSet, 'admin-user') router.register(r'v1/admin-user', api.AdminUserViewSet, 'admin-user')
router.register(r'v1/system-user', api.SystemUserViewSet, 'system-user') router.register(r'v1/system-user', api.SystemUserViewSet, 'system-user')
router.register(r'v1/labels', api.LabelViewSet, 'label') router.register(r'v1/labels', api.LabelViewSet, 'label')
@ -26,15 +26,15 @@ urlpatterns = [
url(r'^v1/assets/user-assets/$', url(r'^v1/assets/user-assets/$',
api.UserAssetListView.as_view(), name='user-asset-list'), api.UserAssetListView.as_view(), name='user-asset-list'),
# update the asset group, which add or delete the asset to the group # update the asset group, which add or delete the asset to the group
url(r'^v1/groups/(?P<pk>[0-9a-zA-Z\-]{36})/assets/$', #url(r'^v1/groups/(?P<pk>[0-9a-zA-Z\-]{36})/assets/$',
api.GroupUpdateAssetsApi.as_view(), name='group-update-assets'), # api.GroupUpdateAssetsApi.as_view(), name='group-update-assets'),
url(r'^v1/groups/(?P<pk>[0-9a-zA-Z\-]{36})/assets/add/$', #url(r'^v1/groups/(?P<pk>[0-9a-zA-Z\-]{36})/assets/add/$',
api.GroupAddAssetsApi.as_view(), name='group-add-assets'), # api.GroupAddAssetsApi.as_view(), name='group-add-assets'),
# update the Cluster, and add or delete the assets to the Cluster # update the Cluster, and add or delete the assets to the Cluster
url(r'^v1/cluster/(?P<pk>[0-9a-zA-Z\-]{36})/assets/$', #url(r'^v1/cluster/(?P<pk>[0-9a-zA-Z\-]{36})/assets/$',
api.ClusterAddAssetsApi.as_view(), name='cluster-add-assets'), # api.ClusterAddAssetsApi.as_view(), name='cluster-add-assets'),
url(r'^v1/cluster/(?P<pk>[0-9a-zA-Z\-]{36})/assets/connective/$', #url(r'^v1/cluster/(?P<pk>[0-9a-zA-Z\-]{36})/assets/connective/$',
api.ClusterTestAssetsAliveApi.as_view(), name='cluster-test-connective'), # api.ClusterTestAssetsAliveApi.as_view(), name='cluster-test-connective'),
url(r'^v1/admin-user/(?P<pk>[0-9a-zA-Z\-]{36})/clusters/$', url(r'^v1/admin-user/(?P<pk>[0-9a-zA-Z\-]{36})/clusters/$',
api.AdminUserAddClustersApi.as_view(), name='admin-user-add-clusters'), api.AdminUserAddClustersApi.as_view(), name='admin-user-add-clusters'),
url(r'^v1/admin-user/(?P<pk>[0-9a-zA-Z\-]{36})/connective/$', url(r'^v1/admin-user/(?P<pk>[0-9a-zA-Z\-]{36})/connective/$',

View File

@ -20,20 +20,20 @@ urlpatterns = [
# User asset view # User asset view
url(r'^user-asset/$', views.UserAssetListView.as_view(), name='user-asset-list'), url(r'^user-asset/$', views.UserAssetListView.as_view(), name='user-asset-list'),
# Resource asset group url # # Resource asset group url
url(r'^asset-group/$', views.AssetGroupListView.as_view(), name='asset-group-list'), # url(r'^asset-group/$', views.AssetGroupListView.as_view(), name='asset-group-list'),
url(r'^asset-group/create/$', views.AssetGroupCreateView.as_view(), name='asset-group-create'), # url(r'^asset-group/create/$', views.AssetGroupCreateView.as_view(), name='asset-group-create'),
url(r'^asset-group/(?P<pk>[0-9a-zA-Z\-]{36})/$', views.AssetGroupDetailView.as_view(), name='asset-group-detail'), # url(r'^asset-group/(?P<pk>[0-9a-zA-Z\-]{36})/$', views.AssetGroupDetailView.as_view(), name='asset-group-detail'),
url(r'^asset-group/(?P<pk>[0-9a-zA-Z\-]{36})/update/$', views.AssetGroupUpdateView.as_view(), name='asset-group-update'), # url(r'^asset-group/(?P<pk>[0-9a-zA-Z\-]{36})/update/$', views.AssetGroupUpdateView.as_view(), name='asset-group-update'),
url(r'^asset-group/(?P<pk>[0-9a-zA-Z\-]{36})/delete/$', views.AssetGroupDeleteView.as_view(), name='asset-group-delete'), # url(r'^asset-group/(?P<pk>[0-9a-zA-Z\-]{36})/delete/$', views.AssetGroupDeleteView.as_view(), name='asset-group-delete'),
# Resource cluster url # Resource cluster url
url(r'^cluster/$', views.ClusterListView.as_view(), name='cluster-list'), # url(r'^cluster/$', views.ClusterListView.as_view(), name='cluster-list'),
url(r'^cluster/create/$', views.ClusterCreateView.as_view(), name='cluster-create'), # url(r'^cluster/create/$', views.ClusterCreateView.as_view(), name='cluster-create'),
url(r'^cluster/(?P<pk>[0-9a-zA-Z\-]{36})/$', views.ClusterDetailView.as_view(), name='cluster-detail'), # url(r'^cluster/(?P<pk>[0-9a-zA-Z\-]{36})/$', views.ClusterDetailView.as_view(), name='cluster-detail'),
url(r'^cluster/(?P<pk>[0-9a-zA-Z\-]{36})/update/', views.ClusterUpdateView.as_view(), name='cluster-update'), # url(r'^cluster/(?P<pk>[0-9a-zA-Z\-]{36})/update/', views.ClusterUpdateView.as_view(), name='cluster-update'),
url(r'^cluster/(?P<pk>[0-9a-zA-Z\-]{36})/delete/$', views.ClusterDeleteView.as_view(), name='cluster-delete'), # url(r'^cluster/(?P<pk>[0-9a-zA-Z\-]{36})/delete/$', views.ClusterDeleteView.as_view(), name='cluster-delete'),
url(r'^cluster/(?P<pk>[0-9a-zA-Z\-]{36})/assets/$', views.ClusterAssetsView.as_view(), name='cluster-assets'), # url(r'^cluster/(?P<pk>[0-9a-zA-Z\-]{36})/assets/$', views.ClusterAssetsView.as_view(), name='cluster-assets'),
# Resource admin user url # Resource admin user url
url(r'^admin-user/$', views.AdminUserListView.as_view(), name='admin-user-list'), url(r'^admin-user/$', views.AdminUserListView.as_view(), name='admin-user-list'),

View File

@ -1,9 +1,8 @@
# coding:utf-8 # coding:utf-8
from .asset import * from .asset import *
from .group import * # from .group import *
from .cluster import * # from .cluster import *
from .system_user import * from .system_user import *
from .admin_user import * from .admin_user import *
from .label import * from .label import *
from .tree import * from .tree import *

View File

@ -3,16 +3,14 @@
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from rest_framework.views import APIView, Response from rest_framework.views import APIView, Response
from rest_framework.generics import ListAPIView, get_object_or_404, RetrieveUpdateAPIView from rest_framework.generics import ListAPIView, get_object_or_404
from rest_framework import viewsets from rest_framework import viewsets
from common.utils import get_object_or_none from users.permissions import IsValidUser, IsSuperUser, IsSuperUserOrAppUser
from users.permissions import IsValidUser, IsSuperUser, IsAppUser, IsSuperUserOrAppUser from .utils import NodePermissionUtil
from .utils import get_user_granted_assets, get_user_granted_asset_groups, \ from .models import NodePermission
get_user_group_granted_assets, get_user_group_granted_asset_groups from .hands import AssetGrantedSerializer, User, UserGroup, Asset, \
from .models import AssetPermission, NodePermission NodeGrantedSerializer, SystemUser
from .hands import AssetGrantedSerializer, User, UserGroup, Node, Asset, \
AssetGroup, AssetGroupGrantedSerializer, SystemUser, MyAssetGroupGrantedSerializer
from . import serializers from . import serializers
@ -37,80 +35,6 @@ class AssetPermissionViewSet(viewsets.ModelViewSet):
return queryset return queryset
class AssetPermissionRemoveUserApi(RetrieveUpdateAPIView):
"""
将用户从授权中移除Detail页面会调用
"""
permission_classes = (IsSuperUser,)
serializer_class = serializers.AssetPermissionUpdateUserSerializer
queryset = AssetPermission.objects.all()
def update(self, request, *args, **kwargs):
perm = self.get_object()
serializer = self.serializer_class(data=request.data)
if serializer.is_valid():
users = serializer.validated_data.get('users')
if users:
perm.users.remove(*tuple(users))
return Response({"msg": "ok"})
else:
return Response({"error": serializer.errors})
class AssetPermissionAddUserApi(RetrieveUpdateAPIView):
permission_classes = (IsSuperUser,)
serializer_class = serializers.AssetPermissionUpdateUserSerializer
queryset = AssetPermission.objects.all()
def update(self, request, *args, **kwargs):
perm = self.get_object()
serializer = self.serializer_class(data=request.data)
if serializer.is_valid():
users = serializer.validated_data.get('users')
if users:
perm.users.add(*tuple(users))
return Response({"msg": "ok"})
else:
return Response({"error": serializer.errors})
class AssetPermissionRemoveAssetApi(RetrieveUpdateAPIView):
"""
将用户从授权中移除Detail页面会调用
"""
permission_classes = (IsSuperUser,)
serializer_class = serializers.AssetPermissionUpdateAssetSerializer
queryset = AssetPermission.objects.all()
def update(self, request, *args, **kwargs):
perm = self.get_object()
serializer = self.serializer_class(data=request.data)
if serializer.is_valid():
assets = serializer.validated_data.get('assets')
if assets:
perm.assets.remove(*tuple(assets))
return Response({"msg": "ok"})
else:
return Response({"error": serializer.errors})
class AssetPermissionAddAssetApi(RetrieveUpdateAPIView):
permission_classes = (IsSuperUser,)
serializer_class = serializers.AssetPermissionUpdateAssetSerializer
queryset = AssetPermission.objects.all()
def update(self, request, *args, **kwargs):
perm = self.get_object()
serializer = self.serializer_class(data=request.data)
if serializer.is_valid():
assets = serializer.validated_data.get('assets')
if assets:
perm.assets.add(*tuple(assets))
return Response({"msg": "ok"})
else:
return Response({"error": serializer.errors})
class UserGrantedAssetsApi(ListAPIView): class UserGrantedAssetsApi(ListAPIView):
""" """
用户授权的所有资产 用户授权的所有资产
@ -120,41 +44,25 @@ class UserGrantedAssetsApi(ListAPIView):
def get_queryset(self): def get_queryset(self):
user_id = self.kwargs.get('pk', '') user_id = self.kwargs.get('pk', '')
queryset = [] queryset = []
if user_id: if user_id:
user = get_object_or_404(User, id=user_id) user = get_object_or_404(User, id=user_id)
for k, v in get_user_granted_assets(user).items(): else:
k.system_users_granted = v user = self.request.user
queryset.append(k)
for k, v in NodePermissionUtil.get_user_assets(user).items():
k.system_users_granted = v
queryset.append(k)
return queryset return queryset
def get_permissions(self):
class UserGrantedAssetGroupsApi(APIView): if self.kwargs.get('pk') is None:
permission_classes = (IsValidUser,) self.permission_classes = (IsValidUser,)
return super().get_permissions()
def get(self, request, *args, **kwargs):
asset_groups = {}
user_id = kwargs.get('pk', '')
user = get_object_or_404(User, id=user_id)
assets = get_user_granted_assets(user)
for asset in assets:
for asset_group in asset.groups.all():
if asset_group.id in asset_groups:
asset_groups[asset_group.id]['assets_amount'] += 1
else:
asset_groups[asset_group.id] = {
'id': asset_group.id,
'name': asset_group.name,
'comment': asset_group.comment,
'assets_amount': 1
}
asset_groups_json = asset_groups.values()
return Response(asset_groups_json, status=200)
class UserGrantedAssetGroupsWithAssetsApi(ListAPIView): class UserGrantedNodesWithAssetsApi(ListAPIView):
""" """
授权用户的资产组这里的资产组并非是授权列表中授权的 授权用户的资产组这里的资产组并非是授权列表中授权的
而是把所有资产取出来然后反查出所有资产组然后合并得到 而是把所有资产取出来然后反查出所有资产组然后合并得到
@ -163,7 +71,7 @@ class UserGrantedAssetGroupsWithAssetsApi(ListAPIView):
[ [
{ {
"id": 1, "id": 1,
"name": "资产组1", "value": "node",
... 其它属性 ... 其它属性
"assets_granted": [ "assets_granted": [
{ {
@ -183,133 +91,28 @@ class UserGrantedAssetGroupsWithAssetsApi(ListAPIView):
] ]
""" """
permission_classes = (IsSuperUserOrAppUser,) permission_classes = (IsSuperUserOrAppUser,)
serializer_class = AssetGroupGrantedSerializer serializer_class = NodeGrantedSerializer
def get_queryset(self): def get_queryset(self):
user_id = self.kwargs.get('pk', '') user_id = self.kwargs.get('pk', '')
queryset = []
if not user_id: if not user_id:
return [] user = self.request.user
else:
user = get_object_or_404(User, id=user_id)
user = get_object_or_404(User, id=user_id) nodes = NodePermissionUtil.get_user_nodes_with_assets(user)
asset_groups = get_user_granted_asset_groups(user) for node, v in nodes.items():
for asset in v['assets']:
queryset = [] asset.system_users_granted = v['system_users']
for asset_group, assets_system_users in asset_groups.items(): node.assets_granted = v['assets']
assets = [] queryset.append(node)
for asset, system_users in assets_system_users:
asset.system_users_granted = system_users
assets.append(asset)
asset_group.assets_granted = assets
queryset.append(asset_group)
return queryset return queryset
def get_permissions(self):
class MyGrantedAssetsApi(ListAPIView): if self.kwargs.get('pk') is None:
""" self.permission_classes = (IsValidUser,)
用户自己查询授权的资产列表 return super().get_permissions()
"""
permission_classes = (IsValidUser,)
serializer_class = AssetGrantedSerializer
def get_queryset(self):
queryset = []
user = self.request.user
if user:
for asset, system_users in get_user_granted_assets(user).items():
asset.system_users_granted = system_users
queryset.append(asset)
return queryset
class MyGrantedAssetGroupsApi(APIView):
"""
授权的所有资产组并非是授权列表中的而是经过计算得来的
"""
permission_classes = (IsValidUser,)
def get(self, request, *args, **kwargs):
asset_groups = {}
user = request.user
if user:
assets = get_user_granted_assets(user)
for asset in assets:
for asset_group in asset.groups.all():
if asset_group.id in asset_groups:
asset_groups[asset_group.id]['assets_amount'] += 1
else:
asset_groups[asset_group.id] = {
'id': asset_group.id,
'name': asset_group.name,
'comment': asset_group.comment,
'assets_amount': 1
}
asset_groups_json = asset_groups.values()
return Response(asset_groups_json, status=200)
class MyGrantedAssetGroupsWithAssetsApi(ListAPIView):
"""
授权当前用户的资产组这里的资产组并非是授权列表中授权的
而是把所有资产取出来然后反查出所有资产组然后合并得到
结果里也包含资产组下授权的资产
数据结构如下
[
{
"id": 1,
"name": "资产组1",
... 其它属性
"assets_granted": [
{
"id": 1,
"hostname": "testserver",
"system_users_granted": [
"id": 1,
"name": "web",
"username": "web",
"protocol": "ssh",
]
}
]
}
]
"""
permission_classes = (IsValidUser,)
serializer_class = MyAssetGroupGrantedSerializer
def get_queryset(self):
user = self.request.user
asset_groups = get_user_granted_asset_groups(user)
queryset = []
for asset_group, assets_system_users in asset_groups.items():
assets = []
for asset, system_users in assets_system_users:
asset.system_users_granted = system_users
assets.append(asset)
asset_group.assets_granted = assets
queryset.append(asset_group)
return queryset
class MyAssetGroupOfAssetsApi(ListAPIView):
"""授权用户资产组下的资产列表, 非该资产组的所有资产,而是被授权的"""
permission_classes = (IsValidUser,)
serializer_class = AssetGrantedSerializer
def get_queryset(self):
queryset = []
asset_group_id = self.kwargs.get('pk', -1)
user = self.request.user
asset_group = get_object_or_none(AssetGroup, id=asset_group_id)
if user and asset_group:
assets = get_user_granted_assets(user)
for asset in asset_group.assets.all():
if asset in assets:
asset.system_users_granted = assets[asset]
queryset.append(asset)
return queryset
class UserGroupGrantedAssetsApi(ListAPIView): class UserGroupGrantedAssetsApi(ListAPIView):
@ -318,27 +121,37 @@ class UserGroupGrantedAssetsApi(ListAPIView):
def get_queryset(self): def get_queryset(self):
user_group_id = self.kwargs.get('pk', '') user_group_id = self.kwargs.get('pk', '')
queryset = []
if user_group_id: if not user_group_id:
user_group = get_object_or_404(UserGroup, id=user_group_id) return queryset
queryset = get_user_group_granted_assets(user_group)
else: user_group = get_object_or_404(UserGroup, id=user_group_id)
queryset = [] assets = NodePermissionUtil.get_user_group_assets(user_group)
for k, v in assets.items():
k.system_users_granted = v
queryset.append(k)
return queryset return queryset
class UserGroupGrantedAssetGroupsApi(ListAPIView): class UserGroupGrantedNodeApi(ListAPIView):
permission_classes = (IsSuperUser,) permission_classes = (IsSuperUser,)
serializer_class = AssetGroupGrantedSerializer serializer_class = NodeGrantedSerializer
def get_queryset(self): def get_queryset(self):
user_group_id = self.kwargs.get('pk', '') user_group_id = self.kwargs.get('pk', '')
queryset = []
if user_group_id: if not user_group_id:
user_group = get_object_or_404(UserGroup, id=user_group_id) return queryset
queryset = get_user_group_granted_asset_groups(user_group)
else: user_group = get_object_or_404(UserGroup, id=user_group_id)
queryset = [] 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']
queryset.append(node)
return queryset return queryset
@ -355,7 +168,7 @@ class ValidateUserAssetPermissionView(APIView):
asset = get_object_or_404(Asset, id=asset_id) asset = get_object_or_404(Asset, id=asset_id)
system_user = get_object_or_404(SystemUser, id=system_id) system_user = get_object_or_404(SystemUser, id=system_id)
assets_granted = get_user_granted_assets(user) assets_granted = NodePermissionUtil.get_user_assets(user)
if system_user in assets_granted.get(asset, []): if system_user in assets_granted.get(asset, []):
return Response({'msg': True}, status=200) return Response({'msg': True}, status=200)
else: else:

View File

@ -4,7 +4,7 @@
from users.utils import AdminUserRequiredMixin from users.utils import AdminUserRequiredMixin
from users.models import User, UserGroup from users.models import User, UserGroup
from assets.models import Asset, AssetGroup, SystemUser, Node from assets.models import Asset, AssetGroup, SystemUser, Node
from assets.serializers import AssetGrantedSerializer, AssetGroupGrantedSerializer, MyAssetGroupGrantedSerializer from assets.serializers import AssetGrantedSerializer, NodeGrantedSerializer

View File

@ -10,26 +10,13 @@ router = routers.DefaultRouter()
router.register('v1/asset-permissions', api.AssetPermissionViewSet, 'asset-permission') router.register('v1/asset-permissions', api.AssetPermissionViewSet, 'asset-permission')
urlpatterns = [ urlpatterns = [
# 用户可以使用自己的Token或其它认证查看自己授权的资产,资产组等
url(r'^v1/user/my/assets/$', api.MyGrantedAssetsApi.as_view(), name='my-assets'),
url(r'^v1/user/my/asset-groups/$', api.MyGrantedAssetGroupsApi.as_view(), name='my-asset-groups'),
url(r'^v1/user/my/asset-groups-assets/$', api.MyGrantedAssetGroupsWithAssetsApi.as_view(), name='my-asset-group-assets'),
url(r'^v1/user/my/asset-group/(?P<pk>[0-9a-zA-Z\-]{36})/assets/$', api.MyAssetGroupOfAssetsApi.as_view(), name='my-asset-group-of-assets'),
# 查询某个用户授权的资产和资产组 # 查询某个用户授权的资产和资产组
url(r'^v1/user/(?P<pk>[0-9a-zA-Z\-]{36})/assets/$', api.UserGrantedAssetsApi.as_view(), name='user-assets'), url(r'^v1/user/(?P<pk>[0-9a-zA-Z\-]{36})?/?assets/$', api.UserGrantedAssetsApi.as_view(), name='user-assets'),
url(r'^v1/user/(?P<pk>[0-9a-zA-Z\-]{36})/asset-groups/$', api.UserGrantedAssetGroupsApi.as_view(), name='user-asset-groups'), url(r'^v1/user/(?P<pk>[0-9a-zA-Z\-]{36})?/?nodes/$', api.UserGrantedNodesWithAssetsApi.as_view(), name='user-nodes'),
url(r'^v1/user/(?P<pk>[0-9a-zA-Z\-]{36})/asset-groups-assets/$', api.UserGrantedAssetGroupsWithAssetsApi.as_view(), name='user-asset-groups'),
# 查询某个用户组授权的资产和资产组 # 查询某个用户组授权的资产和资产组
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})/assets/$', api.UserGroupGrantedAssetsApi.as_view(), name='user-group-assets'),
url(r'^v1/user-group/(?P<pk>[0-9a-zA-Z\-]{36})/asset-groups/$', api.UserGroupGrantedAssetGroupsApi.as_view(), name='user-group-asset-groups'), url(r'^v1/user-group/(?P<pk>[0-9a-zA-Z\-]{36})/nodes/$', api.UserGroupGrantedNodeApi.as_view(), name='user-group-asset-groups'),
# 用户和资产授权变更
url(r'^v1/asset-permissions/(?P<pk>[0-9a-zA-Z\-]{36})/user/remove/$', api.AssetPermissionRemoveUserApi.as_view(), name='asset-permission-remove-user'),
url(r'^v1/asset-permissions/(?P<pk>[0-9a-zA-Z\-]{36})/user/add/$', api.AssetPermissionAddUserApi.as_view(), name='asset-permission-add-user'),
url(r'^v1/asset-permissions/(?P<pk>[0-9a-zA-Z\-]{36})/asset/remove/$', api.AssetPermissionRemoveAssetApi.as_view(), name='asset-permission-remove-asset'),
url(r'^v1/asset-permissions/(?P<pk>[0-9a-zA-Z\-]{36})/asset/add/$', api.AssetPermissionAddAssetApi.as_view(), name='asset-permission-add-asset'),
# 验证用户是否有某个资产和系统用户的权限 # 验证用户是否有某个资产和系统用户的权限
url(r'v1/asset-permission/user/validate/$', api.ValidateUserAssetPermissionView.as_view(), name='validate-user-asset-permission'), url(r'v1/asset-permission/user/validate/$', api.ValidateUserAssetPermissionView.as_view(), name='validate-user-asset-permission'),

View File

@ -20,6 +20,12 @@ class NodePermissionUtil:
.filter(is_active=True) \ .filter(is_active=True) \
.filter(date_expired__gt=timezone.now()) .filter(date_expired__gt=timezone.now())
@staticmethod
def get_system_user_permissions(system_user):
return system_user.nodepermission_set.all() \
.filter(is_active=True) \
.filter(date_expired__gt=timezone.now())
@classmethod @classmethod
def get_user_group_nodes(cls, user_group): def get_user_group_nodes(cls, user_group):
""" """
@ -35,171 +41,233 @@ class NodePermissionUtil:
nodes = copy.deepcopy(nodes_directed) nodes = copy.deepcopy(nodes_directed)
for node, system_users in nodes_directed.items(): for node, system_users in nodes_directed.items():
for child in node.get_all_children(): for child in node.get_family():
nodes[child].update(system_users) nodes[child].update(system_users)
return nodes return nodes
@classmethod @classmethod
def get_user_group(cls): def get_user_group_nodes_with_assets(cls, user_group):
pass """
获取用户组授权的节点和系统用户节点下带有资产
:param user_group:
:return: {"node": {"assets": "", "system_user": ""}, {}}
"""
nodes = cls.get_user_group_nodes(user_group)
nodes_with_assets = dict()
for node, system_users in nodes.items():
nodes_with_assets[node] = {
'assets': node.get_assets(),
'system_users': system_users
}
return nodes_with_assets
@classmethod
def get_user_group_assets(cls, user_group):
assets = collections.defaultdict(set)
permissions = cls.get_user_group_permissions(user_group)
for perm in permissions:
for asset in perm.node.get_all_assets():
assets[asset].add(perm.system_user)
return assets
@classmethod
def get_user_nodes(cls, user):
nodes = collections.defaultdict(set)
groups = user.groups.all()
for group in groups:
group_nodes = cls.get_user_group_nodes(group)
for node, system_users in group_nodes.items():
nodes[node].update(system_users)
return nodes
@classmethod
def get_user_nodes_with_assets(cls, user):
nodes = cls.get_user_nodes(user)
nodes_with_assets = dict()
for node, system_users in nodes.items():
nodes_with_assets[node] = {
'assets': node.get_assets(),
'system_users': system_users
}
return nodes_with_assets
@classmethod
def get_user_assets(cls, user):
assets = collections.defaultdict(set)
nodes_with_assets = cls.get_user_nodes_with_assets(user)
for v in nodes_with_assets.values():
for asset in v['assets']:
assets[asset].update(v['system_users'])
return assets
@classmethod
def get_system_user_assets(cls, system_user):
assets = set()
permissions = cls.get_system_user_permissions(system_user)
for perm in permissions:
assets.update(perm.node.get_all_assets())
return assets
def get_user_group_granted_asset_groups(user_group): # def get_user_group_granted_asset_groups(user_group):
"""Return asset groups granted of the user group # """Return asset groups granted of the user group
#
:param user_group: Instance of :class: ``UserGroup`` # :param user_group: Instance of :class: ``UserGroup``
:return: {asset_group1: {system_user1, }, # :return: {asset_group1: {system_user1, },
asset_group2: {system_user1, system_user2}} # asset_group2: {system_user1, system_user2}}
""" # """
asset_groups = {} # asset_groups = {}
asset_permissions = user_group.asset_permissions.all() # asset_permissions = user_group.asset_permissions.all()
#
for asset_permission in asset_permissions: # for asset_permission in asset_permissions:
if not asset_permission.is_valid: # if not asset_permission.is_valid:
continue # continue
for asset_group in asset_permission.asset_groups.all(): # for asset_group in asset_permission.asset_groups.all():
if asset_group in asset_groups: # if asset_group in asset_groups:
asset_groups[asset_group] |= set(asset_permission.system_users.all()) # asset_groups[asset_group] |= set(asset_permission.system_users.all())
else: # else:
asset_groups[asset_group] = set(asset_permission.system_users.all()) # asset_groups[asset_group] = set(asset_permission.system_users.all())
return asset_groups # return asset_groups
#
#
def get_user_group_granted_assets(user_group): # def get_user_group_granted_assets(user_group):
"""Return assets granted of the user group # """Return assets granted of the user group
#
:param user_group: Instance of :class: ``UserGroup`` # :param user_group: Instance of :class: ``UserGroup``
:return: {asset1: {system_user1, }, asset1: {system_user1, system_user2]} # :return: {asset1: {system_user1, }, asset1: {system_user1, system_user2]}
""" # """
assets = {} # assets = {}
asset_permissions = user_group.asset_permissions.all() # asset_permissions = user_group.asset_permissions.all()
#
for asset_permission in asset_permissions: # for asset_permission in asset_permissions:
if not asset_permission.is_valid: # if not asset_permission.is_valid:
continue # continue
for asset in asset_permission.get_granted_assets(): # for asset in asset_permission.get_granted_assets():
if not asset.is_active: # if not asset.is_active:
continue # continue
if asset in assets: # if asset in assets:
assets[asset] |= set(asset_permission.system_users.all()) # assets[asset] |= set(asset_permission.system_users.all())
else: # else:
assets[asset] = set(asset_permission.system_users.all()) # assets[asset] = set(asset_permission.system_users.all())
return assets # return assets
#
#
def get_user_granted_assets_direct(user): # def get_user_granted_assets_direct(user):
"""Return assets granted of the user directly # """Return assets granted of the user directly
#
:param user: Instance of :class: ``User`` # :param user: Instance of :class: ``User``
:return: {asset1: {system_user1, system_user2}, asset2: {...}} # :return: {asset1: {system_user1, system_user2}, asset2: {...}}
""" # """
assets = {} # assets = {}
asset_permissions_direct = user.asset_permissions.all() # asset_permissions_direct = user.asset_permissions.all()
#
for asset_permission in asset_permissions_direct: # for asset_permission in asset_permissions_direct:
if not asset_permission.is_valid: # if not asset_permission.is_valid:
continue # continue
for asset in asset_permission.get_granted_assets(): # for asset in asset_permission.get_granted_assets():
if not asset.is_active: # if not asset.is_active:
continue # continue
if asset in assets: # if asset in assets:
assets[asset] |= set(asset_permission.system_users.all()) # assets[asset] |= set(asset_permission.system_users.all())
else: # else:
setattr(asset, 'inherited', False) # setattr(asset, 'inherited', False)
assets[asset] = set(asset_permission.system_users.all()) # assets[asset] = set(asset_permission.system_users.all())
return assets # return assets
#
#
def get_user_granted_assets_inherit_from_user_groups(user): # def get_user_granted_assets_inherit_from_user_groups(user):
"""Return assets granted of the user inherit from user groups # """Return assets granted of the user inherit from user groups
#
:param user: Instance of :class: ``User`` # :param user: Instance of :class: ``User``
:return: {asset1: {system_user1, system_user2}, asset2: {...}} # :return: {asset1: {system_user1, system_user2}, asset2: {...}}
""" # """
assets = {} # assets = {}
user_groups = user.groups.all() # user_groups = user.groups.all()
#
for user_group in user_groups: # for user_group in user_groups:
assets_inherited = get_user_group_granted_assets(user_group) # assets_inherited = get_user_group_granted_assets(user_group)
for asset in assets_inherited: # for asset in assets_inherited:
if not asset.is_active: # if not asset.is_active:
continue # continue
if asset in assets: # if asset in assets:
assets[asset] |= assets_inherited[asset] # assets[asset] |= assets_inherited[asset]
else: # else:
setattr(asset, 'inherited', True) # setattr(asset, 'inherited', True)
assets[asset] = assets_inherited[asset] # assets[asset] = assets_inherited[asset]
return assets # return assets
#
#
def get_user_granted_assets(user): # def get_user_granted_assets(user):
"""Return assets granted of the user inherit from user groups # """Return assets granted of the user inherit from user groups
#
:param user: Instance of :class: ``User`` # :param user: Instance of :class: ``User``
:return: {asset1: {system_user1, system_user2}, asset2: {...}} # :return: {asset1: {system_user1, system_user2}, asset2: {...}}
""" # """
assets_direct = get_user_granted_assets_direct(user) # assets_direct = get_user_granted_assets_direct(user)
assets_inherited = get_user_granted_assets_inherit_from_user_groups(user) # assets_inherited = get_user_granted_assets_inherit_from_user_groups(user)
assets = assets_inherited # assets = assets_inherited
#
for asset in assets_direct: # for asset in assets_direct:
if not asset.is_active: # if not asset.is_active:
continue # continue
if asset in assets: # if asset in assets:
assets[asset] |= assets_direct[asset] # assets[asset] |= assets_direct[asset]
else: # else:
assets[asset] = assets_direct[asset] # assets[asset] = assets_direct[asset]
return assets # return assets
#
#
def get_user_granted_asset_groups(user): # def get_user_granted_asset_groups(user):
"""Return asset groups with assets and system users, it's not the asset # """Return asset groups with assets and system users, it's not the asset
group direct permed in rules. We get all asset and then get it asset group # group direct permed in rules. We get all asset and then get it asset group
#
:param user: Instance of :class: ``User`` # :param user: Instance of :class: ``User``
:return: {asset_group1: [asset1, asset2], asset_group2: []} # :return: {asset_group1: [asset1, asset2], asset_group2: []}
""" # """
asset_groups = collections.defaultdict(list) # asset_groups = collections.defaultdict(list)
ungroups = [AssetGroup(name="UnGrouped")] # ungroups = [AssetGroup(name="UnGrouped")]
for asset, system_users in get_user_granted_assets(user).items(): # for asset, system_users in get_user_granted_assets(user).items():
groups = asset.groups.all() # groups = asset.groups.all()
if not groups: # if not groups:
groups = ungroups # groups = ungroups
for asset_group in groups: # for asset_group in groups:
asset_groups[asset_group].append((asset, system_users)) # asset_groups[asset_group].append((asset, system_users))
return asset_groups # return asset_groups
#
#
def get_user_group_asset_permissions(user_group): # def get_user_group_asset_permissions(user_group):
permissions = user_group.asset_permissions.all() # permissions = user_group.asset_permissions.all()
return permissions # return permissions
#
#
def get_user_asset_permissions(user): # def get_user_asset_permissions(user):
user_group_permissions = set() # user_group_permissions = set()
direct_permissions = set(setattr_bulk(user.asset_permissions.all(), 'inherited', 0)) # direct_permissions = set(setattr_bulk(user.asset_permissions.all(), 'inherited', 0))
#
for user_group in user.groups.all(): # for user_group in user.groups.all():
permissions = get_user_group_asset_permissions(user_group) # permissions = get_user_group_asset_permissions(user_group)
user_group_permissions |= set(permissions) # user_group_permissions |= set(permissions)
user_group_permissions = set(setattr_bulk(user_group_permissions, 'inherited', 1)) # user_group_permissions = set(setattr_bulk(user_group_permissions, 'inherited', 1))
return direct_permissions | user_group_permissions # return direct_permissions | user_group_permissions
#
#
def get_user_granted_system_users(user): # def get_user_granted_system_users(user):
""" # """
:param user: the user # :param user: the user
:return: {"system_user": ["asset", "asset1"], "system_user": []} # :return: {"system_user": ["asset", "asset1"], "system_user": []}
""" # """
assets = get_user_granted_assets(user) # assets = get_user_granted_assets(user)
system_users_dict = {} # system_users_dict = {}
for asset, system_users in assets.items(): # for asset, system_users in assets.items():
for system_user in system_users: # for system_user in system_users:
if system_user in system_users_dict: # if system_user in system_users_dict:
system_users_dict[system_user].append(asset) # system_users_dict[system_user].append(asset)
else: # else:
system_users_dict[system_user] = [asset] # system_users_dict[system_user] = [asset]
return system_users_dict # return system_users_dict
def push_system_user(assets, system_user): def push_system_user(assets, system_user):