From 4a1aeefb82be03ef5232f3abb512c7c83b0b0ea2 Mon Sep 17 00:00:00 2001 From: "Jiangjie.Bai" Date: Thu, 29 Sep 2022 16:18:12 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E3=80=81=E7=94=A8=E6=88=B7=E7=BB=84=E5=AF=B9=E4=BA=8E=E6=8E=88?= =?UTF-8?q?=E6=9D=83=E8=B4=A6=E5=8F=B7=E7=9A=84API=E8=8E=B7=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/perms/api/user_group_permission.py | 15 +++++++ apps/perms/api/user_permission/common.py | 52 ++++++++++++++++-------- apps/perms/models/asset_permission.py | 35 +++++++++++----- apps/perms/urls/asset_permission.py | 11 +++-- 4 files changed, 83 insertions(+), 30 deletions(-) diff --git a/apps/perms/api/user_group_permission.py b/apps/perms/api/user_group_permission.py index 6d45de865..0a88c4228 100644 --- a/apps/perms/api/user_group_permission.py +++ b/apps/perms/api/user_group_permission.py @@ -20,6 +20,7 @@ __all__ = [ 'UserGroupGrantedNodeAssetsApi', 'UserGroupGrantedNodeChildrenAsTreeApi', 'UserGroupGrantedAssetSystemUsersApi', + 'UserGroupGrantedAssetAccountsApi', ] @@ -203,3 +204,17 @@ class UserGroupGrantedNodeChildrenAsTreeApi(SerializeToTreeNodeMixin, ListAPIVie class UserGroupGrantedAssetSystemUsersApi(UserGroupMixin, uapi.UserGrantedAssetSystemUsersForAdminApi): def get_asset_system_user_ids_with_actions(self, asset): return get_asset_system_user_ids_with_actions_by_group(self.group, asset) + + +class UserGroupGrantedAssetAccountsApi(uapi.UserGrantedAssetAccountsApi): + + @lazyproperty + def user_group(self): + group_id = self.kwargs.get('pk') + return UserGroup.objects.get(id=group_id) + + def get_queryset(self): + accounts = AssetPermission.get_perm_asset_accounts( + user_group=self.user_group, asset=self.asset + ) + return accounts diff --git a/apps/perms/api/user_permission/common.py b/apps/perms/api/user_permission/common.py index 52d3a4f31..8d80a481c 100644 --- a/apps/perms/api/user_permission/common.py +++ b/apps/perms/api/user_permission/common.py @@ -30,8 +30,10 @@ __all__ = [ 'ValidateUserAssetPermissionApi', 'GetUserAssetPermissionActionsApi', 'MyGrantedAssetSystemUsersApi', - 'UserGrantedAssetAccounts', - 'MyGrantedAssetAccounts', + 'UserGrantedAssetAccountsApi', + 'MyGrantedAssetAccountsApi', + 'UserGrantedAssetSpecialAccountsApi', + 'MyGrantedAssetSpecialAccountsApi', ] @@ -143,7 +145,7 @@ class MyGrantedAssetSystemUsersApi(UserGrantedAssetSystemUsersForAdminApi): return self.request.user -class UserGrantedAssetAccounts(ListAPIView): +class UserGrantedAssetAccountsApi(ListAPIView): serializer_class = serializers.AccountsGrantedSerializer rbac_perms = { 'list': 'perms.view_userassets' @@ -162,22 +164,40 @@ class UserGrantedAssetAccounts(ListAPIView): return asset def get_queryset(self): - accounts = AssetPermission.get_user_perm_asset_accounts( - self.user, self.asset, with_actions=True - ) + accounts = AssetPermission.get_perm_asset_accounts(user=self.user, asset=self.asset) return accounts - # @INPUT @USER - # inner_accounts = [ - # Account.get_input_account(), Account.get_user_account(self.user.username) - # ] - # for inner_account in inner_accounts: - # inner_account.actions = Action.ALL - # accounts = accounts + inner_accounts - # 构造默认包含的账号,如: @INPUT @USER - # return accounts -class MyGrantedAssetAccounts(UserGrantedAssetAccounts): +class MyGrantedAssetAccountsApi(UserGrantedAssetAccountsApi): + permission_classes = (IsValidUser,) + + @lazyproperty + def user(self): + return self.request.user + + +class UserGrantedAssetSpecialAccountsApi(ListAPIView): + serializer_class = serializers.AccountsGrantedSerializer + rbac_perms = { + 'list': 'perms.view_userassets' + } + + @lazyproperty + def user(self): + return self.request.user + + def get_queryset(self): + # 构造默认包含的账号,如: @INPUT @USER + accounts = [ + Account.get_input_account(), + Account.get_user_account(self.user.username) + ] + for account in accounts: + account.actions = Action.ALL + return accounts + + +class MyGrantedAssetSpecialAccountsApi(UserGrantedAssetSpecialAccountsApi): permission_classes = (IsValidUser,) @lazyproperty diff --git a/apps/perms/models/asset_permission.py b/apps/perms/models/asset_permission.py index 76da872f8..660b8cc5b 100644 --- a/apps/perms/models/asset_permission.py +++ b/apps/perms/models/asset_permission.py @@ -225,10 +225,10 @@ class AssetPermission(OrgModelMixin): return accounts @classmethod - def get_user_perm_asset_accounts(cls, user, asset: Asset, with_actions=False): - perms = cls.filter(user, asset) - all_account_names = cls.retrieve_account_names(perms) - accounts = asset.filter_accounts(all_account_names) + def get_perm_asset_accounts(cls, user=None, user_group=None, asset=None, with_actions=True): + perms = cls.filter(user=user, user_group=user_group, asset=asset) + account_names = cls.retrieve_account_names(perms) + accounts = asset.filter_accounts(account_names) if with_actions: cls.set_accounts_actions(accounts, perms=perms) return accounts @@ -257,15 +257,20 @@ class AssetPermission(OrgModelMixin): return account_names @classmethod - def filter(cls, user=None, asset=None, account_names=None): - """ 获取同时包含 用户-资产-账号 的授权规则 """ + def filter(cls, user=None, user_group=None, asset=None, account_names=None): + """ 获取同时包含 用户(组)-资产-账号 的授权规则 """ perm_ids = [] if user: - user_assetperm_ids = cls.filter_by_user(user, flat=True) - perm_ids.append(user_assetperm_ids) + user_perm_ids = cls.filter_by_user(user, flat=True) + perm_ids.append(user_perm_ids) + + if user_group: + user_group_perm_ids = cls.filter_by_user_group(user_group, flat=True) + perm_ids.append(user_group_perm_ids) + if asset: - asset_assetperm_ids = cls.filter_by_asset(asset, flat=True) - perm_ids.append(asset_assetperm_ids) + asset_perm_ids = cls.filter_by_asset(asset, flat=True) + perm_ids.append(asset_perm_ids) # & 是同时满足,比如有用户,但是用户的规则是空,那么返回也应该是空 perm_ids = list(reduce(lambda x, y: set(x) & set(y), perm_ids)) perms = cls.objects.filter(id__in=perm_ids) @@ -291,6 +296,16 @@ class AssetPermission(OrgModelMixin): perms = cls.objects.filter(id__in=perm_ids).valid() return perms + @classmethod + def filter_by_user_group(cls, user_group, flat=False): + perm_ids = AssetPermission.user_groups.through.objects.filter( + usergroup_id=user_group + ).values_list('assetpermission_id', flat=True) + if flat: + return set(perm_ids) + perms = cls.objects.filter(id__in=perm_ids).valid() + return perms + @classmethod def filter_by_asset(cls, asset, with_node=True, flat=False): perm_ids = set() diff --git a/apps/perms/urls/asset_permission.py b/apps/perms/urls/asset_permission.py index 5606ee639..5973dd0ae 100644 --- a/apps/perms/urls/asset_permission.py +++ b/apps/perms/urls/asset_permission.py @@ -65,10 +65,13 @@ user_permission_urlpatterns = [ path('/assets//system-users/', api.UserGrantedAssetSystemUsersForAdminApi.as_view(), name='user-asset-system-users'), path('assets//system-users/', api.MyGrantedAssetSystemUsersApi.as_view(), name='my-asset-system-users'), - # Todo: v3 增加 + # Todo: v3 增加 Done. # 获取所有和资产-用户关联的账号列表 - path('/assets//accounts/', api.UserGrantedAssetAccounts.as_view(), name='user-asset-accounts'), - path('assets//accounts/', api.MyGrantedAssetAccounts.as_view(), name='my-asset-accounts') + path('/assets//accounts/', api.UserGrantedAssetAccountsApi.as_view(), name='user-asset-accounts'), + path('assets//accounts/', api.MyGrantedAssetAccountsApi.as_view(), name='my-asset-accounts'), + # 用户登录资产的特殊账号, @INPUT, @USER 等 + path('/assets/special-accounts/', api.UserGrantedAssetSpecialAccountsApi.as_view(), name='user-special-accounts'), + path('/assets/special-accounts/', api.MyGrantedAssetSpecialAccountsApi.as_view(), name='my-special-accounts'), ] user_group_permission_urlpatterns = [ @@ -83,7 +86,7 @@ user_group_permission_urlpatterns = [ path('/assets//system-users/', api.UserGroupGrantedAssetSystemUsersApi.as_view(), name='user-group-asset-system-users'), # Todo: v3 增加 # 获取所有和资产-用户组关联的账号列表 - path('/assets//accounts/', api.UserGrantedAssetAccounts.as_view(), name='user-asset-accounts'), + path('/assets//accounts/', api.UserGroupGrantedAssetAccountsApi.as_view(), name='user-group-asset-accounts'), ] permission_urlpatterns = [