From d80cbe270a2b000fb7643519886752d95c924fde Mon Sep 17 00:00:00 2001 From: ibuler Date: Thu, 23 Nov 2017 11:26:17 +0800 Subject: [PATCH] =?UTF-8?q?[Update]=20=E4=BF=AE=E6=94=B9=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E8=87=AA=E5=B7=B1=E6=8E=88=E6=9D=83=E8=B5=84?= =?UTF-8?q?=E4=BA=A7=E7=9A=84api=EF=BC=8C=E5=92=8C=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E6=8E=88=E6=9D=83=E8=B5=84=E4=BA=A7=E7=BB=84?= =?UTF-8?q?=E7=AD=89api=E7=9A=84Url=E5=92=8C=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/serializers.py | 30 +++++++- apps/perms/api.py | 147 +++++++++++++++++++++++++++--------- apps/perms/hands.py | 2 +- apps/perms/urls/api_urls.py | 7 +- 4 files changed, 144 insertions(+), 42 deletions(-) diff --git a/apps/assets/serializers.py b/apps/assets/serializers.py index a68a8de74..def2577c8 100644 --- a/apps/assets/serializers.py +++ b/apps/assets/serializers.py @@ -155,8 +155,8 @@ class AssetGrantedSerializer(serializers.ModelSerializer): class Meta(object): model = Asset - fields = ("id", "hostname", "ip", "port", "system_users_granted", "is_inherited", - "is_active", "system_users_join", "comment") + fields = ("id", "hostname", "ip", "port", "system_users_granted", + "is_inherited", "is_active", "system_users_join", "comment") @staticmethod def get_is_inherited(obj): @@ -167,7 +167,17 @@ class AssetGrantedSerializer(serializers.ModelSerializer): @staticmethod def get_system_users_join(obj): - return ', '.join([system_user.username for system_user in obj.system_users_granted]) + return ', '.join([system_user.username + for system_user in obj.system_users_granted]) + + +class MyAssetGrantedSerializer(AssetGrantedSerializer): + """Remove ip and port from asset for security""" + + class Meta(object): + model = Asset + fields = ("id", "hostname", "system_users_granted", "is_inherited", + "is_active", "system_users_join", "comment") class IDCSerializer(BulkSerializerMixin, serializers.ModelSerializer): @@ -200,3 +210,17 @@ class AssetGroupGrantedSerializer(BulkSerializerMixin, serializers.ModelSerializ @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) diff --git a/apps/perms/api.py b/apps/perms/api.py index 1713f8623..0ed395e20 100644 --- a/apps/perms/api.py +++ b/apps/perms/api.py @@ -12,12 +12,15 @@ 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 from .hands import AssetGrantedSerializer, User, UserGroup, AssetGroup, Asset, \ - AssetGroup, AssetGroupGrantedSerializer, SystemUser + AssetGroup, AssetGroupGrantedSerializer, SystemUser, MyAssetGroupGrantedSerializer from . import serializers from .utils import associate_system_users_and_assets class AssetPermissionViewSet(viewsets.ModelViewSet): + """ + 资产授权列表的增删改查api + """ queryset = AssetPermission.objects.all() serializer_class = serializers.AssetPermissionSerializer permission_classes = (IsSuperUser,) @@ -63,6 +66,9 @@ class AssetPermissionViewSet(viewsets.ModelViewSet): class RevokeUserAssetPermission(APIView): + """ + 将用户从授权中移除,Detail页面会调用 + """ permission_classes = (IsSuperUser,) def put(self, request, *args, **kwargs): @@ -80,7 +86,9 @@ class RevokeUserAssetPermission(APIView): class RemoveSystemUserAssetPermission(APIView): - """将系统用户从授权中移除, Detail页面会调用""" + """ + 将系统用户从授权中移除, Detail页面会调用 + """ permission_classes = (IsSuperUser,) def put(self, request, *args, **kwargs): @@ -101,6 +109,9 @@ class RemoveSystemUserAssetPermission(APIView): class RevokeUserGroupAssetPermission(APIView): + """ + 将用户组从授权中删除 + """ permission_classes = (IsSuperUser,) def put(self, request, *args, **kwargs): @@ -118,6 +129,9 @@ class RevokeUserGroupAssetPermission(APIView): class UserGrantedAssetsApi(ListAPIView): + """ + 用户授权的所有资产 + """ permission_classes = (IsSuperUserOrAppUser,) serializer_class = AssetGrantedSerializer @@ -133,7 +147,58 @@ class UserGrantedAssetsApi(ListAPIView): return queryset -class UserGrantedAssetGroupsApi(ListAPIView): +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) + + +class UserGrantedAssetGroupsWithAssetsApi(ListAPIView): + """ + 授权用户的资产组,注:这里的资产组并非是授权列表中授权的, + 而是把所有资产取出来,然后反查出所有资产组,然后合并得到, + 结果里也包含资产组下授权的资产 + 数据结构如下: + [ + { + "id": 1, + "name": "资产组1", + ... 其它属性 + "assets_granted": [ + { + "id": 1, + "hostname": "testserver", + "ip": "192.168.1.1", + "port": 22, + "system_users_granted": [ + "id": 1, + "name": "web", + "username": "web", + "protocol": "ssh", + ] + } + ] + } + ] + """ permission_classes = (IsSuperUserOrAppUser,) serializer_class = AssetGroupGrantedSerializer @@ -157,9 +222,8 @@ class UserGrantedAssetGroupsApi(ListAPIView): class MyGrantedAssetsApi(ListAPIView): - """授权给用户的资产列表 - [{'hostname': 'x','ip': 'x', .., - 'system_users_granted': [{'name': 'x', .}, ...] + """ + 用户自己查询授权的资产列表 """ permission_classes = (IsValidUser,) serializer_class = AssetGrantedSerializer @@ -174,10 +238,9 @@ class MyGrantedAssetsApi(ListAPIView): return queryset -class MyGrantedAssetsGroupsApi(APIView): +class MyGrantedAssetGroupsApi(APIView): """ - 授权给用户的资产组列表, 非直接通过授权规则授权的资产组列表, 而是授权资产的所有 - 资产组之和 + 授权的所有资产组,并非是授权列表中的,而是经过计算得来的 """ permission_classes = (IsValidUser,) @@ -202,36 +265,48 @@ class MyGrantedAssetsGroupsApi(APIView): return Response(asset_groups_json, status=200) -class MyAssetGroupAssetsApi(ListAPIView): +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(self, request, *args, **kwargs): - asset_groups = dict() - asset_groups[0] = { - 'id': 0, 'name': 'ungrouped', 'assets': [] - } - user = request.user + def get_queryset(self): + user = self.request.user + asset_groups = get_user_granted_asset_groups(user) - if user: - assets = get_user_granted_assets(user) - for asset, system_users in assets.items(): - asset_json = asset.to_json() - asset_json['system_users'] = [su.to_json() for su in system_users] - if not asset.groups.all(): - asset_groups[0]['assets'].append(asset_json) - continue - for asset_group in asset.groups.all(): - if asset_group.id in asset_groups: - asset_groups[asset_group.id]['assets'].append(asset_json) - else: - asset_groups[asset_group.id] = { - 'id': asset_group.id, - 'name': asset_group.name, - 'comment': asset_group.comment, - 'assets': [asset_json], - } - asset_groups_json = asset_groups.values() - return Response(asset_groups_json, status=200) + 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): diff --git a/apps/perms/hands.py b/apps/perms/hands.py index 0bcf07576..54af4f788 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 -from assets.serializers import AssetGrantedSerializer, AssetGroupGrantedSerializer +from assets.serializers import AssetGrantedSerializer, AssetGroupGrantedSerializer, MyAssetGroupGrantedSerializer diff --git a/apps/perms/urls/api_urls.py b/apps/perms/urls/api_urls.py index 27b3c47bb..da5a3e800 100644 --- a/apps/perms/urls/api_urls.py +++ b/apps/perms/urls/api_urls.py @@ -17,10 +17,10 @@ urlpatterns = [ api.MyGrantedAssetsApi.as_view(), name='my-assets'), url(r'^v1/user/my/asset-groups/$', - api.MyGrantedAssetsGroupsApi.as_view(), + api.MyGrantedAssetGroupsApi.as_view(), name='my-asset-groups'), url(r'^v1/user/my/asset-groups-assets/$', - api.MyAssetGroupAssetsApi.as_view(), + api.MyGrantedAssetGroupsWithAssetsApi.as_view(), name='my-asset-group-assets'), url(r'^v1/user/my/asset-group/(?P[0-9]+)/assets/$', api.MyAssetGroupOfAssetsApi.as_view(), @@ -33,6 +33,9 @@ urlpatterns = [ url(r'^v1/user/(?P[0-9]+)/asset-groups/$', api.UserGrantedAssetGroupsApi.as_view(), name='user-asset-groups'), + url(r'^v1/user/(?P[0-9]+)/asset-groups-assets/$', + api.UserGrantedAssetGroupsWithAssetsApi.as_view(), + name='user-asset-groups'), # 查询某个用户组授权的资产和资产组 url(r'^v1/user-group/(?P[0-9]+)/assets/$',