Merge branch 'v3' of github.com:jumpserver/jumpserver into v3

pull/8931/head
ibuler 2022-09-23 19:00:09 +08:00
commit f223cf43cc
5 changed files with 39 additions and 23 deletions

View File

@ -9,6 +9,10 @@ __all__ = ['Account', 'AccountTemplate']
class Account(BaseAccount): class Account(BaseAccount):
class InnerAccount(models.TextChoices):
INPUT = '@INPUT', '@INPUT'
USER = '@USER', '@USER'
asset = models.ForeignKey( asset = models.ForeignKey(
'assets.Asset', related_name='accounts', 'assets.Asset', related_name='accounts',
on_delete=models.CASCADE, verbose_name=_('Asset') on_delete=models.CASCADE, verbose_name=_('Asset')
@ -40,6 +44,16 @@ class Account(BaseAccount):
def __str__(self): def __str__(self):
return '{}@{}'.format(self.username, self.asset.name) return '{}@{}'.format(self.username, self.asset.name)
@classmethod
def get_input_account(cls):
""" @INPUT 手动登录的账号(any) """
return cls(name=cls.InnerAccount.INPUT.value, username='')
@classmethod
def get_user_account(cls, username):
""" @USER 动态用户的账号(self) """
return cls(name=cls.InnerAccount.USER.value, username=username)
class AccountTemplate(BaseAccount): class AccountTemplate(BaseAccount):
class Meta: class Meta:

View File

@ -4,8 +4,6 @@
import logging import logging
import uuid import uuid
from functools import reduce
from collections import Iterable
from django.db import models from django.db import models
from django.db.models import Q from django.db.models import Q
@ -180,9 +178,11 @@ class Asset(AbsConnectivity, NodesRelationMixin, JMSOrgBaseModel):
return tree_node return tree_node
def filter_accounts(self, account_names=None): def filter_accounts(self, account_names=None):
from perms.models import AssetPermission
if account_names is None: if account_names is None:
return self.accounts.all() return self.accounts.all()
assert isinstance(account_names, Iterable), '`account_names` must be an iterable object' if AssetPermission.SpecialAccount.ALL in account_names:
return self.accounts.all()
queries = Q(name__in=account_names) | Q(username__in=account_names) queries = Q(name__in=account_names) | Q(username__in=account_names)
accounts = self.accounts.filter(queries) accounts = self.accounts.filter(queries)
return accounts return accounts

View File

@ -19,7 +19,7 @@ from perms.utils.permission import (
from common.permissions import IsValidUser from common.permissions import IsValidUser
from common.utils import get_logger, lazyproperty from common.utils import get_logger, lazyproperty
from perms.hands import User, Asset from perms.hands import User, Asset, Account
from perms import serializers from perms import serializers
from perms.models import AssetPermission from perms.models import AssetPermission
@ -150,7 +150,7 @@ class UserGrantedAssetAccounts(ListAPIView):
} }
@lazyproperty @lazyproperty
def user(self): def user(self) -> User:
user_id = self.kwargs.get('pk') user_id = self.kwargs.get('pk')
return User.objects.get(id=user_id) return User.objects.get(id=user_id)
@ -163,11 +163,14 @@ class UserGrantedAssetAccounts(ListAPIView):
def get_queryset(self): def get_queryset(self):
# 获取用户-资产的授权规则 # 获取用户-资产的授权规则
assetperms = AssetPermission.filter_permissions(self.user, self.asset) assetperms = AssetPermission.filter(self.user, self.asset)
account_names = AssetPermission.get_account_names(assetperms) account_names = AssetPermission.get_account_names(assetperms)
accounts = self.asset.filter_accounts(account_names) accounts = list(self.asset.filter_accounts(account_names))
# @INPUT @USER
inner_accounts = [Account.get_input_account(), Account.get_user_account(self.user.username)]
all_accounts = accounts + inner_accounts
# 构造默认包含的账号,如: @INPUT @USER # 构造默认包含的账号,如: @INPUT @USER
return accounts return all_accounts
class MyGrantedAssetAccounts(UserGrantedAssetAccounts): class MyGrantedAssetAccounts(UserGrantedAssetAccounts):

View File

@ -2,12 +2,12 @@
# #
from users.models import User, UserGroup from users.models import User, UserGroup
from assets.models import Asset, Node, Label, FavoriteAsset from assets.models import Asset, Node, Label, FavoriteAsset, Account
from assets.serializers import NodeSerializer from assets.serializers import NodeSerializer
__all__ = [ __all__ = [
'User', 'UserGroup', 'User', 'UserGroup',
'Asset', 'Node', 'Label', 'FavoriteAsset', 'Asset', 'Node', 'Label', 'FavoriteAsset',
'NodeSerializer', 'NodeSerializer', 'Account'
] ]

View File

@ -83,6 +83,9 @@ class AssetPermissionManager(OrgManager):
class AssetPermission(OrgModelMixin): class AssetPermission(OrgModelMixin):
class SpecialAccount(models.TextChoices):
ALL = '@ALL', 'All'
id = models.UUIDField(default=uuid.uuid4, primary_key=True) id = models.UUIDField(default=uuid.uuid4, primary_key=True)
name = models.CharField(max_length=128, verbose_name=_('Name')) name = models.CharField(max_length=128, verbose_name=_('Name'))
users = models.ManyToManyField('users.User', blank=True, verbose_name=_("User"), users = models.ManyToManyField('users.User', blank=True, verbose_name=_("User"),
@ -113,11 +116,6 @@ class AssetPermission(OrgModelMixin):
objects = AssetPermissionManager.from_queryset(AssetPermissionQuerySet)() objects = AssetPermissionManager.from_queryset(AssetPermissionQuerySet)()
class SpecialAccount(models.TextChoices):
ALL = '@ALL', 'All'
INPUT = '@INPUT', 'Input'
USER = '@USER', 'User'
class Meta: class Meta:
unique_together = [('org_id', 'name')] unique_together = [('org_id', 'name')]
verbose_name = _("Asset permission") verbose_name = _("Asset permission")
@ -232,17 +230,17 @@ class AssetPermission(OrgModelMixin):
return account_names return account_names
@classmethod @classmethod
def filter_permissions(cls, user=None, asset=None, account=None): def filter(cls, user=None, asset=None, account=None):
""" 获取同时包含 用户-资产-账号 的授权规则 """ """ 获取同时包含 用户-资产-账号 的授权规则 """
assetperm_ids = [] assetperm_ids = []
if user: if user:
user_assetperm_ids = cls.filter_permissions_by_user(user, flat=True) user_assetperm_ids = cls.filter_by_user(user, flat=True)
assetperm_ids.append(user_assetperm_ids) assetperm_ids.append(user_assetperm_ids)
if asset: if asset:
asset_assetperm_ids = cls.filter_permissions_by_asset(asset, flat=True) asset_assetperm_ids = cls.filter_by_asset(asset, flat=True)
assetperm_ids.append(asset_assetperm_ids) assetperm_ids.append(asset_assetperm_ids)
if account: if account:
account_assetperm_ids = cls.filter_permissions_by_account(account, flat=True) account_assetperm_ids = cls.filter_by_account(account, flat=True)
assetperm_ids.append(account_assetperm_ids) assetperm_ids.append(account_assetperm_ids)
# & 是同时满足,比如有用户,但是用户的规则是空,那么返回也应该是空 # & 是同时满足,比如有用户,但是用户的规则是空,那么返回也应该是空
assetperm_ids = list(reduce(lambda x, y: set(x) & set(y), assetperm_ids)) assetperm_ids = list(reduce(lambda x, y: set(x) & set(y), assetperm_ids))
@ -250,7 +248,7 @@ class AssetPermission(OrgModelMixin):
return assetperms return assetperms
@classmethod @classmethod
def filter_permissions_by_user(cls, user, with_group=True, flat=False): def filter_by_user(cls, user, with_group=True, flat=False):
assetperm_ids = set() assetperm_ids = set()
user_assetperm_ids = AssetPermission.users.through.objects \ user_assetperm_ids = AssetPermission.users.through.objects \
.filter(user_id=user.id) \ .filter(user_id=user.id) \
@ -273,7 +271,7 @@ class AssetPermission(OrgModelMixin):
return assetperms return assetperms
@classmethod @classmethod
def filter_permissions_by_asset(cls, asset, with_node=True, flat=False): def filter_by_asset(cls, asset, with_node=True, flat=False):
assetperm_ids = set() assetperm_ids = set()
asset_assetperm_ids = AssetPermission.assets.through.objects \ asset_assetperm_ids = AssetPermission.assets.through.objects \
.filter(asset_id=asset.id) \ .filter(asset_id=asset.id) \
@ -294,8 +292,9 @@ class AssetPermission(OrgModelMixin):
return assetperms return assetperms
@classmethod @classmethod
def filter_permissions_by_account(cls, account, flat=False): def filter_by_account(cls, account, flat=False):
assetperms = cls.objects.filter(accounts__contains=account).valid() queries = Q(accounts__contains=account) | Q(accounts__contains=cls.SpecialAccount.ALL.value)
assetperms = cls.objects.filter(queries).valid()
if flat: if flat:
assetperm_ids = assetperms.values_list('id', flat=True) assetperm_ids = assetperms.values_list('id', flat=True)
return assetperm_ids return assetperm_ids