From 3bb6e089859430774cf6b6b98c258a5d03c21561 Mon Sep 17 00:00:00 2001 From: ibuler Date: Wed, 7 Feb 2018 23:25:15 +0800 Subject: [PATCH] =?UTF-8?q?[Feature]=20=E6=9B=B4=E6=94=B9perms=20api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/api/{cluster.py => __cluster.py} | 0 apps/assets/api/{group.py => __group.py} | 0 apps/assets/api/__init__.py | 4 +- apps/assets/api/asset.py | 10 +- apps/assets/api/{tree.py => node.py} | 0 apps/assets/hands.py | 2 +- apps/assets/models/tree.py | 12 +- apps/assets/serializers.py | 345 ----------------- apps/assets/serializers/__init__.py | 8 + apps/assets/serializers/admin_user.py | 52 +++ apps/assets/serializers/asset.py | 67 ++++ apps/assets/serializers/cluster.py | 46 +++ apps/assets/serializers/label.py | 37 ++ apps/assets/serializers/node.py | 58 +++ apps/assets/serializers/system_user.py | 57 +++ apps/assets/urls/api_urls.py | 20 +- apps/assets/urls/views_urls.py | 24 +- apps/assets/views/__init__.py | 5 +- apps/perms/api.py | 301 +++------------ apps/perms/hands.py | 2 +- apps/perms/urls/api_urls.py | 19 +- apps/perms/utils.py | 386 +++++++++++-------- 22 files changed, 649 insertions(+), 806 deletions(-) rename apps/assets/api/{cluster.py => __cluster.py} (100%) rename apps/assets/api/{group.py => __group.py} (100%) rename apps/assets/api/{tree.py => node.py} (100%) delete mode 100644 apps/assets/serializers.py create mode 100644 apps/assets/serializers/__init__.py create mode 100644 apps/assets/serializers/admin_user.py create mode 100644 apps/assets/serializers/asset.py create mode 100644 apps/assets/serializers/cluster.py create mode 100644 apps/assets/serializers/label.py create mode 100644 apps/assets/serializers/node.py create mode 100644 apps/assets/serializers/system_user.py diff --git a/apps/assets/api/cluster.py b/apps/assets/api/__cluster.py similarity index 100% rename from apps/assets/api/cluster.py rename to apps/assets/api/__cluster.py diff --git a/apps/assets/api/group.py b/apps/assets/api/__group.py similarity index 100% rename from apps/assets/api/group.py rename to apps/assets/api/__group.py diff --git a/apps/assets/api/__init__.py b/apps/assets/api/__init__.py index 4aa9966b6..4a41c0706 100644 --- a/apps/assets/api/__init__.py +++ b/apps/assets/api/__init__.py @@ -1,7 +1,5 @@ from .admin_user import * from .asset import * -from .cluster import * -from .group import * from .label import * from .system_user import * -from .tree import * \ No newline at end of file +from .node import * diff --git a/apps/assets/api/asset.py b/apps/assets/api/asset.py index bc7aa0409..1f75b49fc 100644 --- a/apps/assets/api/asset.py +++ b/apps/assets/api/asset.py @@ -12,7 +12,7 @@ from django.db.models import Q from common.mixins import IDInFilterMixin from common.utils import get_logger from ..hands import IsSuperUser, IsValidUser, IsSuperUserOrAppUser, \ - get_user_granted_assets + NodePermissionUtil from ..models import Asset, SystemUser, AdminUser, Node from .. import serializers from ..tasks import update_asset_hardware_info_manual, \ @@ -41,16 +41,10 @@ class AssetViewSet(IDInFilterMixin, LabelFilter, BulkModelViewSet): def get_queryset(self): 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') system_user_id = self.request.query_params.get('system_user_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: admin_user = get_object_or_404(AdminUser, id=admin_user_id) assets_direct = [asset.id for asset in admin_user.asset_set.all()] @@ -72,7 +66,7 @@ class UserAssetListView(generics.ListAPIView): permission_classes = (IsValidUser,) 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( id__in=[asset.id for asset in assets_granted] ) diff --git a/apps/assets/api/tree.py b/apps/assets/api/node.py similarity index 100% rename from apps/assets/api/tree.py rename to apps/assets/api/node.py diff --git a/apps/assets/hands.py b/apps/assets/hands.py index c160051bb..403a08633 100644 --- a/apps/assets/hands.py +++ b/apps/assets/hands.py @@ -14,5 +14,5 @@ from users.utils import AdminUserRequiredMixin from users.permissions import IsAppUser, IsSuperUser, IsValidUser, IsSuperUserOrAppUser 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 \ No newline at end of file diff --git a/apps/assets/models/tree.py b/apps/assets/models/tree.py index 1a4e51588..a62b3c1bd 100644 --- a/apps/assets/models/tree.py +++ b/apps/assets/models/tree.py @@ -47,16 +47,20 @@ class Node(models.Model): def get_all_children(self): 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): from .asset import Asset - children = self.get_children() - assets = Asset.objects.filter(nodes__in=children) + assets = Asset.objects.filter(nodes__id=self.id) return assets def get_all_assets(self): from .asset import Asset - children = self.get_all_children() - assets = Asset.objects.filter(nodes__in=children) + nodes = self.get_family() + assets = Asset.objects.filter(nodes__in=nodes) return assets @property diff --git a/apps/assets/serializers.py b/apps/assets/serializers.py deleted file mode 100644 index b7cc0ee9a..000000000 --- a/apps/assets/serializers.py +++ /dev/null @@ -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'] diff --git a/apps/assets/serializers/__init__.py b/apps/assets/serializers/__init__.py new file mode 100644 index 000000000..c39d34767 --- /dev/null +++ b/apps/assets/serializers/__init__.py @@ -0,0 +1,8 @@ +# -*- coding: utf-8 -*- +# + +from .asset import * +from .admin_user import * +from .label import * +from .system_user import * +from .node import * diff --git a/apps/assets/serializers/admin_user.py b/apps/assets/serializers/admin_user.py new file mode 100644 index 000000000..d38105106 --- /dev/null +++ b/apps/assets/serializers/admin_user.py @@ -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'] \ No newline at end of file diff --git a/apps/assets/serializers/asset.py b/apps/assets/serializers/asset.py new file mode 100644 index 000000000..5b5588757 --- /dev/null +++ b/apps/assets/serializers/asset.py @@ -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", + ) diff --git a/apps/assets/serializers/cluster.py b/apps/assets/serializers/cluster.py new file mode 100644 index 000000000..43724a4a2 --- /dev/null +++ b/apps/assets/serializers/cluster.py @@ -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()) diff --git a/apps/assets/serializers/label.py b/apps/assets/serializers/label.py new file mode 100644 index 000000000..b45e1e508 --- /dev/null +++ b/apps/assets/serializers/label.py @@ -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]) diff --git a/apps/assets/serializers/node.py b/apps/assets/serializers/node.py new file mode 100644 index 000000000..88a270917 --- /dev/null +++ b/apps/assets/serializers/node.py @@ -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'] \ No newline at end of file diff --git a/apps/assets/serializers/system_user.py b/apps/assets/serializers/system_user.py new file mode 100644 index 000000000..488d9bb66 --- /dev/null +++ b/apps/assets/serializers/system_user.py @@ -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') \ No newline at end of file diff --git a/apps/assets/urls/api_urls.py b/apps/assets/urls/api_urls.py index 0e14cda21..8847b6397 100644 --- a/apps/assets/urls/api_urls.py +++ b/apps/assets/urls/api_urls.py @@ -7,9 +7,9 @@ app_name = 'assets' 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/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/system-user', api.SystemUserViewSet, 'system-user') router.register(r'v1/labels', api.LabelViewSet, 'label') @@ -26,15 +26,15 @@ urlpatterns = [ url(r'^v1/assets/user-assets/$', api.UserAssetListView.as_view(), name='user-asset-list'), # update the asset group, which add or delete the asset to the group - url(r'^v1/groups/(?P[0-9a-zA-Z\-]{36})/assets/$', - api.GroupUpdateAssetsApi.as_view(), name='group-update-assets'), - url(r'^v1/groups/(?P[0-9a-zA-Z\-]{36})/assets/add/$', - api.GroupAddAssetsApi.as_view(), name='group-add-assets'), + #url(r'^v1/groups/(?P[0-9a-zA-Z\-]{36})/assets/$', + # api.GroupUpdateAssetsApi.as_view(), name='group-update-assets'), + #url(r'^v1/groups/(?P[0-9a-zA-Z\-]{36})/assets/add/$', + # api.GroupAddAssetsApi.as_view(), name='group-add-assets'), # update the Cluster, and add or delete the assets to the Cluster - url(r'^v1/cluster/(?P[0-9a-zA-Z\-]{36})/assets/$', - api.ClusterAddAssetsApi.as_view(), name='cluster-add-assets'), - url(r'^v1/cluster/(?P[0-9a-zA-Z\-]{36})/assets/connective/$', - api.ClusterTestAssetsAliveApi.as_view(), name='cluster-test-connective'), + #url(r'^v1/cluster/(?P[0-9a-zA-Z\-]{36})/assets/$', + # api.ClusterAddAssetsApi.as_view(), name='cluster-add-assets'), + #url(r'^v1/cluster/(?P[0-9a-zA-Z\-]{36})/assets/connective/$', + # api.ClusterTestAssetsAliveApi.as_view(), name='cluster-test-connective'), url(r'^v1/admin-user/(?P[0-9a-zA-Z\-]{36})/clusters/$', api.AdminUserAddClustersApi.as_view(), name='admin-user-add-clusters'), url(r'^v1/admin-user/(?P[0-9a-zA-Z\-]{36})/connective/$', diff --git a/apps/assets/urls/views_urls.py b/apps/assets/urls/views_urls.py index 43d25300e..1704531d2 100644 --- a/apps/assets/urls/views_urls.py +++ b/apps/assets/urls/views_urls.py @@ -20,20 +20,20 @@ urlpatterns = [ # User asset view url(r'^user-asset/$', views.UserAssetListView.as_view(), name='user-asset-list'), - # Resource asset group url - 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/(?P[0-9a-zA-Z\-]{36})/$', views.AssetGroupDetailView.as_view(), name='asset-group-detail'), - url(r'^asset-group/(?P[0-9a-zA-Z\-]{36})/update/$', views.AssetGroupUpdateView.as_view(), name='asset-group-update'), - url(r'^asset-group/(?P[0-9a-zA-Z\-]{36})/delete/$', views.AssetGroupDeleteView.as_view(), name='asset-group-delete'), + # # Resource asset group url + # 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/(?P[0-9a-zA-Z\-]{36})/$', views.AssetGroupDetailView.as_view(), name='asset-group-detail'), + # url(r'^asset-group/(?P[0-9a-zA-Z\-]{36})/update/$', views.AssetGroupUpdateView.as_view(), name='asset-group-update'), + # url(r'^asset-group/(?P[0-9a-zA-Z\-]{36})/delete/$', views.AssetGroupDeleteView.as_view(), name='asset-group-delete'), # Resource cluster url - url(r'^cluster/$', views.ClusterListView.as_view(), name='cluster-list'), - url(r'^cluster/create/$', views.ClusterCreateView.as_view(), name='cluster-create'), - url(r'^cluster/(?P[0-9a-zA-Z\-]{36})/$', views.ClusterDetailView.as_view(), name='cluster-detail'), - url(r'^cluster/(?P[0-9a-zA-Z\-]{36})/update/', views.ClusterUpdateView.as_view(), name='cluster-update'), - url(r'^cluster/(?P[0-9a-zA-Z\-]{36})/delete/$', views.ClusterDeleteView.as_view(), name='cluster-delete'), - url(r'^cluster/(?P[0-9a-zA-Z\-]{36})/assets/$', views.ClusterAssetsView.as_view(), name='cluster-assets'), + # url(r'^cluster/$', views.ClusterListView.as_view(), name='cluster-list'), + # url(r'^cluster/create/$', views.ClusterCreateView.as_view(), name='cluster-create'), + # url(r'^cluster/(?P[0-9a-zA-Z\-]{36})/$', views.ClusterDetailView.as_view(), name='cluster-detail'), + # url(r'^cluster/(?P[0-9a-zA-Z\-]{36})/update/', views.ClusterUpdateView.as_view(), name='cluster-update'), + # url(r'^cluster/(?P[0-9a-zA-Z\-]{36})/delete/$', views.ClusterDeleteView.as_view(), name='cluster-delete'), + # url(r'^cluster/(?P[0-9a-zA-Z\-]{36})/assets/$', views.ClusterAssetsView.as_view(), name='cluster-assets'), # Resource admin user url url(r'^admin-user/$', views.AdminUserListView.as_view(), name='admin-user-list'), diff --git a/apps/assets/views/__init__.py b/apps/assets/views/__init__.py index 597de79e9..3da4b6750 100644 --- a/apps/assets/views/__init__.py +++ b/apps/assets/views/__init__.py @@ -1,9 +1,8 @@ # coding:utf-8 from .asset import * -from .group import * -from .cluster import * +# from .group import * +# from .cluster import * from .system_user import * from .admin_user import * from .label import * from .tree import * - diff --git a/apps/perms/api.py b/apps/perms/api.py index 276ad0c43..0ae5b4e9e 100644 --- a/apps/perms/api.py +++ b/apps/perms/api.py @@ -3,16 +3,14 @@ from django.shortcuts import get_object_or_404 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 common.utils import get_object_or_none -from users.permissions import IsValidUser, IsSuperUser, IsAppUser, IsSuperUserOrAppUser -from .utils import get_user_granted_assets, get_user_granted_asset_groups, \ - get_user_group_granted_assets, get_user_group_granted_asset_groups -from .models import AssetPermission, NodePermission -from .hands import AssetGrantedSerializer, User, UserGroup, Node, Asset, \ - AssetGroup, AssetGroupGrantedSerializer, SystemUser, MyAssetGroupGrantedSerializer +from users.permissions import IsValidUser, IsSuperUser, IsSuperUserOrAppUser +from .utils import NodePermissionUtil +from .models import NodePermission +from .hands import AssetGrantedSerializer, User, UserGroup, Asset, \ + NodeGrantedSerializer, SystemUser from . import serializers @@ -37,80 +35,6 @@ class AssetPermissionViewSet(viewsets.ModelViewSet): 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): """ 用户授权的所有资产 @@ -120,41 +44,25 @@ class UserGrantedAssetsApi(ListAPIView): def get_queryset(self): user_id = self.kwargs.get('pk', '') - queryset = [] + if user_id: user = get_object_or_404(User, id=user_id) - for k, v in get_user_granted_assets(user).items(): - k.system_users_granted = v - queryset.append(k) + else: + user = self.request.user + + for k, v in NodePermissionUtil.get_user_assets(user).items(): + k.system_users_granted = v + queryset.append(k) return queryset - -class UserGrantedAssetGroupsApi(APIView): - permission_classes = (IsValidUser,) - - 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) + def get_permissions(self): + if self.kwargs.get('pk') is None: + self.permission_classes = (IsValidUser,) + return super().get_permissions() -class UserGrantedAssetGroupsWithAssetsApi(ListAPIView): +class UserGrantedNodesWithAssetsApi(ListAPIView): """ 授权用户的资产组,注:这里的资产组并非是授权列表中授权的, 而是把所有资产取出来,然后反查出所有资产组,然后合并得到, @@ -163,7 +71,7 @@ class UserGrantedAssetGroupsWithAssetsApi(ListAPIView): [ { "id": 1, - "name": "资产组1", + "value": "node", ... 其它属性 "assets_granted": [ { @@ -183,133 +91,28 @@ class UserGrantedAssetGroupsWithAssetsApi(ListAPIView): ] """ permission_classes = (IsSuperUserOrAppUser,) - serializer_class = AssetGroupGrantedSerializer + serializer_class = NodeGrantedSerializer def get_queryset(self): user_id = self.kwargs.get('pk', '') + queryset = [] 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) - 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) + nodes = NodePermissionUtil.get_user_nodes_with_assets(user) + 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 - -class MyGrantedAssetsApi(ListAPIView): - """ - 用户自己查询授权的资产列表 - """ - 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 + def get_permissions(self): + if self.kwargs.get('pk') is None: + self.permission_classes = (IsValidUser,) + return super().get_permissions() class UserGroupGrantedAssetsApi(ListAPIView): @@ -318,27 +121,37 @@ class UserGroupGrantedAssetsApi(ListAPIView): def get_queryset(self): user_group_id = self.kwargs.get('pk', '') + queryset = [] - if user_group_id: - user_group = get_object_or_404(UserGroup, id=user_group_id) - queryset = get_user_group_granted_assets(user_group) - else: - queryset = [] + if not user_group_id: + return queryset + + user_group = get_object_or_404(UserGroup, id=user_group_id) + assets = NodePermissionUtil.get_user_group_assets(user_group) + for k, v in assets.items(): + k.system_users_granted = v + queryset.append(k) return queryset -class UserGroupGrantedAssetGroupsApi(ListAPIView): +class UserGroupGrantedNodeApi(ListAPIView): permission_classes = (IsSuperUser,) - serializer_class = AssetGroupGrantedSerializer + serializer_class = NodeGrantedSerializer def get_queryset(self): user_group_id = self.kwargs.get('pk', '') + queryset = [] - if user_group_id: - user_group = get_object_or_404(UserGroup, id=user_group_id) - queryset = get_user_group_granted_asset_groups(user_group) - else: - queryset = [] + if not user_group_id: + return queryset + + user_group = get_object_or_404(UserGroup, id=user_group_id) + nodes = NodePermissionUtil.get_user_group_nodes_with_assets(user_group) + for node, v in nodes.items(): + for asset in v['assets']: + asset.system_users_granted = v['system_users'] + node.assets_granted = v['assets'] + queryset.append(node) return queryset @@ -355,7 +168,7 @@ class ValidateUserAssetPermissionView(APIView): asset = get_object_or_404(Asset, id=asset_id) system_user = get_object_or_404(SystemUser, id=system_id) - assets_granted = get_user_granted_assets(user) + assets_granted = NodePermissionUtil.get_user_assets(user) if system_user in assets_granted.get(asset, []): return Response({'msg': True}, status=200) else: diff --git a/apps/perms/hands.py b/apps/perms/hands.py index 44c97b455..42bb90cef 100644 --- a/apps/perms/hands.py +++ b/apps/perms/hands.py @@ -4,7 +4,7 @@ from users.utils import AdminUserRequiredMixin from users.models import User, UserGroup from assets.models import Asset, AssetGroup, SystemUser, Node -from assets.serializers import AssetGrantedSerializer, AssetGroupGrantedSerializer, MyAssetGroupGrantedSerializer +from assets.serializers import AssetGrantedSerializer, NodeGrantedSerializer diff --git a/apps/perms/urls/api_urls.py b/apps/perms/urls/api_urls.py index a9fad1eac..3c7870fa5 100644 --- a/apps/perms/urls/api_urls.py +++ b/apps/perms/urls/api_urls.py @@ -10,26 +10,13 @@ router = routers.DefaultRouter() router.register('v1/asset-permissions', api.AssetPermissionViewSet, 'asset-permission') 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[0-9a-zA-Z\-]{36})/assets/$', api.MyAssetGroupOfAssetsApi.as_view(), name='my-asset-group-of-assets'), - # 查询某个用户授权的资产和资产组 - url(r'^v1/user/(?P[0-9a-zA-Z\-]{36})/assets/$', api.UserGrantedAssetsApi.as_view(), name='user-assets'), - url(r'^v1/user/(?P[0-9a-zA-Z\-]{36})/asset-groups/$', api.UserGrantedAssetGroupsApi.as_view(), name='user-asset-groups'), - url(r'^v1/user/(?P[0-9a-zA-Z\-]{36})/asset-groups-assets/$', api.UserGrantedAssetGroupsWithAssetsApi.as_view(), name='user-asset-groups'), + url(r'^v1/user/(?P[0-9a-zA-Z\-]{36})?/?assets/$', api.UserGrantedAssetsApi.as_view(), name='user-assets'), + url(r'^v1/user/(?P[0-9a-zA-Z\-]{36})?/?nodes/$', api.UserGrantedNodesWithAssetsApi.as_view(), name='user-nodes'), # 查询某个用户组授权的资产和资产组 url(r'^v1/user-group/(?P[0-9a-zA-Z\-]{36})/assets/$', api.UserGroupGrantedAssetsApi.as_view(), name='user-group-assets'), - url(r'^v1/user-group/(?P[0-9a-zA-Z\-]{36})/asset-groups/$', api.UserGroupGrantedAssetGroupsApi.as_view(), name='user-group-asset-groups'), - - # 用户和资产授权变更 - url(r'^v1/asset-permissions/(?P[0-9a-zA-Z\-]{36})/user/remove/$', api.AssetPermissionRemoveUserApi.as_view(), name='asset-permission-remove-user'), - url(r'^v1/asset-permissions/(?P[0-9a-zA-Z\-]{36})/user/add/$', api.AssetPermissionAddUserApi.as_view(), name='asset-permission-add-user'), - url(r'^v1/asset-permissions/(?P[0-9a-zA-Z\-]{36})/asset/remove/$', api.AssetPermissionRemoveAssetApi.as_view(), name='asset-permission-remove-asset'), - url(r'^v1/asset-permissions/(?P[0-9a-zA-Z\-]{36})/asset/add/$', api.AssetPermissionAddAssetApi.as_view(), name='asset-permission-add-asset'), + url(r'^v1/user-group/(?P[0-9a-zA-Z\-]{36})/nodes/$', api.UserGroupGrantedNodeApi.as_view(), name='user-group-asset-groups'), # 验证用户是否有某个资产和系统用户的权限 url(r'v1/asset-permission/user/validate/$', api.ValidateUserAssetPermissionView.as_view(), name='validate-user-asset-permission'), diff --git a/apps/perms/utils.py b/apps/perms/utils.py index 0cd27dfd9..75299e761 100644 --- a/apps/perms/utils.py +++ b/apps/perms/utils.py @@ -20,6 +20,12 @@ class NodePermissionUtil: .filter(is_active=True) \ .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 def get_user_group_nodes(cls, user_group): """ @@ -35,171 +41,233 @@ class NodePermissionUtil: nodes = copy.deepcopy(nodes_directed) 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) return nodes @classmethod - def get_user_group(cls): - pass + def get_user_group_nodes_with_assets(cls, user_group): + """ + 获取用户组授权的节点和系统用户,节点下带有资产 + :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): - """Return asset groups granted of the user group - - :param user_group: Instance of :class: ``UserGroup`` - :return: {asset_group1: {system_user1, }, - asset_group2: {system_user1, system_user2}} - """ - asset_groups = {} - asset_permissions = user_group.asset_permissions.all() - - for asset_permission in asset_permissions: - if not asset_permission.is_valid: - continue - for asset_group in asset_permission.asset_groups.all(): - if asset_group in asset_groups: - asset_groups[asset_group] |= set(asset_permission.system_users.all()) - else: - asset_groups[asset_group] = set(asset_permission.system_users.all()) - return asset_groups - - -def get_user_group_granted_assets(user_group): - """Return assets granted of the user group - - :param user_group: Instance of :class: ``UserGroup`` - :return: {asset1: {system_user1, }, asset1: {system_user1, system_user2]} - """ - assets = {} - asset_permissions = user_group.asset_permissions.all() - - for asset_permission in asset_permissions: - if not asset_permission.is_valid: - continue - for asset in asset_permission.get_granted_assets(): - if not asset.is_active: - continue - if asset in assets: - assets[asset] |= set(asset_permission.system_users.all()) - else: - assets[asset] = set(asset_permission.system_users.all()) - return assets - - -def get_user_granted_assets_direct(user): - """Return assets granted of the user directly - - :param user: Instance of :class: ``User`` - :return: {asset1: {system_user1, system_user2}, asset2: {...}} - """ - assets = {} - asset_permissions_direct = user.asset_permissions.all() - - for asset_permission in asset_permissions_direct: - if not asset_permission.is_valid: - continue - for asset in asset_permission.get_granted_assets(): - if not asset.is_active: - continue - if asset in assets: - assets[asset] |= set(asset_permission.system_users.all()) - else: - setattr(asset, 'inherited', False) - assets[asset] = set(asset_permission.system_users.all()) - return assets - - -def get_user_granted_assets_inherit_from_user_groups(user): - """Return assets granted of the user inherit from user groups - - :param user: Instance of :class: ``User`` - :return: {asset1: {system_user1, system_user2}, asset2: {...}} - """ - assets = {} - user_groups = user.groups.all() - - for user_group in user_groups: - assets_inherited = get_user_group_granted_assets(user_group) - for asset in assets_inherited: - if not asset.is_active: - continue - if asset in assets: - assets[asset] |= assets_inherited[asset] - else: - setattr(asset, 'inherited', True) - assets[asset] = assets_inherited[asset] - return assets - - -def get_user_granted_assets(user): - """Return assets granted of the user inherit from user groups - - :param user: Instance of :class: ``User`` - :return: {asset1: {system_user1, system_user2}, asset2: {...}} - """ - assets_direct = get_user_granted_assets_direct(user) - assets_inherited = get_user_granted_assets_inherit_from_user_groups(user) - assets = assets_inherited - - for asset in assets_direct: - if not asset.is_active: - continue - if asset in assets: - assets[asset] |= assets_direct[asset] - else: - assets[asset] = assets_direct[asset] - return assets - - -def get_user_granted_asset_groups(user): - """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 - - :param user: Instance of :class: ``User`` - :return: {asset_group1: [asset1, asset2], asset_group2: []} - """ - asset_groups = collections.defaultdict(list) - ungroups = [AssetGroup(name="UnGrouped")] - for asset, system_users in get_user_granted_assets(user).items(): - groups = asset.groups.all() - if not groups: - groups = ungroups - for asset_group in groups: - asset_groups[asset_group].append((asset, system_users)) - return asset_groups - - -def get_user_group_asset_permissions(user_group): - permissions = user_group.asset_permissions.all() - return permissions - - -def get_user_asset_permissions(user): - user_group_permissions = set() - direct_permissions = set(setattr_bulk(user.asset_permissions.all(), 'inherited', 0)) - - for user_group in user.groups.all(): - permissions = get_user_group_asset_permissions(user_group) - user_group_permissions |= set(permissions) - user_group_permissions = set(setattr_bulk(user_group_permissions, 'inherited', 1)) - return direct_permissions | user_group_permissions - - -def get_user_granted_system_users(user): - """ - :param user: the user - :return: {"system_user": ["asset", "asset1"], "system_user": []} - """ - assets = get_user_granted_assets(user) - system_users_dict = {} - for asset, system_users in assets.items(): - for system_user in system_users: - if system_user in system_users_dict: - system_users_dict[system_user].append(asset) - else: - system_users_dict[system_user] = [asset] - return system_users_dict +# def get_user_group_granted_asset_groups(user_group): +# """Return asset groups granted of the user group +# +# :param user_group: Instance of :class: ``UserGroup`` +# :return: {asset_group1: {system_user1, }, +# asset_group2: {system_user1, system_user2}} +# """ +# asset_groups = {} +# asset_permissions = user_group.asset_permissions.all() +# +# for asset_permission in asset_permissions: +# if not asset_permission.is_valid: +# continue +# for asset_group in asset_permission.asset_groups.all(): +# if asset_group in asset_groups: +# asset_groups[asset_group] |= set(asset_permission.system_users.all()) +# else: +# asset_groups[asset_group] = set(asset_permission.system_users.all()) +# return asset_groups +# +# +# def get_user_group_granted_assets(user_group): +# """Return assets granted of the user group +# +# :param user_group: Instance of :class: ``UserGroup`` +# :return: {asset1: {system_user1, }, asset1: {system_user1, system_user2]} +# """ +# assets = {} +# asset_permissions = user_group.asset_permissions.all() +# +# for asset_permission in asset_permissions: +# if not asset_permission.is_valid: +# continue +# for asset in asset_permission.get_granted_assets(): +# if not asset.is_active: +# continue +# if asset in assets: +# assets[asset] |= set(asset_permission.system_users.all()) +# else: +# assets[asset] = set(asset_permission.system_users.all()) +# return assets +# +# +# def get_user_granted_assets_direct(user): +# """Return assets granted of the user directly +# +# :param user: Instance of :class: ``User`` +# :return: {asset1: {system_user1, system_user2}, asset2: {...}} +# """ +# assets = {} +# asset_permissions_direct = user.asset_permissions.all() +# +# for asset_permission in asset_permissions_direct: +# if not asset_permission.is_valid: +# continue +# for asset in asset_permission.get_granted_assets(): +# if not asset.is_active: +# continue +# if asset in assets: +# assets[asset] |= set(asset_permission.system_users.all()) +# else: +# setattr(asset, 'inherited', False) +# assets[asset] = set(asset_permission.system_users.all()) +# return assets +# +# +# def get_user_granted_assets_inherit_from_user_groups(user): +# """Return assets granted of the user inherit from user groups +# +# :param user: Instance of :class: ``User`` +# :return: {asset1: {system_user1, system_user2}, asset2: {...}} +# """ +# assets = {} +# user_groups = user.groups.all() +# +# for user_group in user_groups: +# assets_inherited = get_user_group_granted_assets(user_group) +# for asset in assets_inherited: +# if not asset.is_active: +# continue +# if asset in assets: +# assets[asset] |= assets_inherited[asset] +# else: +# setattr(asset, 'inherited', True) +# assets[asset] = assets_inherited[asset] +# return assets +# +# +# def get_user_granted_assets(user): +# """Return assets granted of the user inherit from user groups +# +# :param user: Instance of :class: ``User`` +# :return: {asset1: {system_user1, system_user2}, asset2: {...}} +# """ +# assets_direct = get_user_granted_assets_direct(user) +# assets_inherited = get_user_granted_assets_inherit_from_user_groups(user) +# assets = assets_inherited +# +# for asset in assets_direct: +# if not asset.is_active: +# continue +# if asset in assets: +# assets[asset] |= assets_direct[asset] +# else: +# assets[asset] = assets_direct[asset] +# return assets +# +# +# def get_user_granted_asset_groups(user): +# """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 +# +# :param user: Instance of :class: ``User`` +# :return: {asset_group1: [asset1, asset2], asset_group2: []} +# """ +# asset_groups = collections.defaultdict(list) +# ungroups = [AssetGroup(name="UnGrouped")] +# for asset, system_users in get_user_granted_assets(user).items(): +# groups = asset.groups.all() +# if not groups: +# groups = ungroups +# for asset_group in groups: +# asset_groups[asset_group].append((asset, system_users)) +# return asset_groups +# +# +# def get_user_group_asset_permissions(user_group): +# permissions = user_group.asset_permissions.all() +# return permissions +# +# +# def get_user_asset_permissions(user): +# user_group_permissions = set() +# direct_permissions = set(setattr_bulk(user.asset_permissions.all(), 'inherited', 0)) +# +# for user_group in user.groups.all(): +# permissions = get_user_group_asset_permissions(user_group) +# user_group_permissions |= set(permissions) +# user_group_permissions = set(setattr_bulk(user_group_permissions, 'inherited', 1)) +# return direct_permissions | user_group_permissions +# +# +# def get_user_granted_system_users(user): +# """ +# :param user: the user +# :return: {"system_user": ["asset", "asset1"], "system_user": []} +# """ +# assets = get_user_granted_assets(user) +# system_users_dict = {} +# for asset, system_users in assets.items(): +# for system_user in system_users: +# if system_user in system_users_dict: +# system_users_dict[system_user].append(asset) +# else: +# system_users_dict[system_user] = [asset] +# return system_users_dict def push_system_user(assets, system_user):