You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
jumpserver/apps/perms/models/perm_node.py

144 lines
4.3 KiB

from django.db import models
from django.db.models import F, TextChoices
from django.utils.translation import gettext_lazy as _
from accounts.models import Account
from assets.models import Asset, Node, FamilyMixin
from common.utils import lazyproperty
from orgs.mixins.models import JMSOrgBaseModel
class NodeFrom(TextChoices):
granted = 'granted', 'Direct node granted'
child = 'child', 'Have children node'
asset = 'asset', 'Direct asset granted'
class UserAssetGrantedTreeNodeRelation(FamilyMixin, JMSOrgBaseModel):
NodeFrom = NodeFrom
id = models.AutoField(
auto_created=True, primary_key=True, serialize=False, verbose_name=_('ID')
)
user = models.ForeignKey('users.User', db_constraint=False, on_delete=models.CASCADE)
node = models.ForeignKey(
'assets.Node', default=None, on_delete=models.CASCADE, db_constraint=False, null=False,
related_name='granted_node_rels'
)
node_key = models.CharField(max_length=64, verbose_name=_("Key"), db_index=True)
node_parent_key = models.CharField(
max_length=64, default='', verbose_name=_('Parent key'), db_index=True
)
node_from = models.CharField(choices=NodeFrom.choices, max_length=16, db_index=True)
node_assets_amount = models.IntegerField(default=0)
comment = ''
def __str__(self):
return f'{self.user}|{self.node}'
@property
def key(self):
return self.node_key
@property
def parent_key(self):
return self.node_parent_key
@classmethod
def get_node_from_with_node(cls, user, key):
""" 获取用户授权的节点的来源
这种情况就是因为 父节点被授权了, 找到是因为那个节点授权, 自己才会出现在授权树中
"""
ancestor_keys = set(cls.get_node_ancestor_keys(key, with_self=True))
# 被授权的祖先节点
# Todo 每个节点都过滤速度不慢吗 ?
ancestor_nodes = cls.objects.filter(user=user, node_key__in=ancestor_keys)
for node in ancestor_nodes:
# 如果是直接授权的节点
if node.key == key:
return node.node_from, node
if node.node_from == cls.NodeFrom.granted:
return node.node_from, None
return '', None
class PermNode(Node):
NodeFrom = NodeFrom
class Meta:
proxy = True
ordering = []
# 特殊节点
UNGROUPED_NODE_KEY = 'ungrouped'
UNGROUPED_NODE_VALUE = _('Ungrouped')
FAVORITE_NODE_KEY = 'favorite'
FAVORITE_NODE_VALUE = _('Favorite')
node_from = ''
granted_assets_amount = 0
annotate_granted_node_rel_fields = {
'granted_assets_amount': F('granted_node_rels__node_assets_amount'),
'node_from': F('granted_node_rels__node_from')
}
def __str__(self):
return f'{self.name}'
def use_granted_assets_amount(self):
self.assets_amount = self.granted_assets_amount
@classmethod
def get_ungrouped_node(cls, assets_amount):
return cls(
id=cls.UNGROUPED_NODE_KEY,
key=cls.UNGROUPED_NODE_KEY,
value=cls.UNGROUPED_NODE_VALUE,
assets_amount=assets_amount
)
@classmethod
def get_favorite_node(cls, assets_amount):
node = cls(
id=cls.FAVORITE_NODE_KEY,
key=cls.FAVORITE_NODE_KEY,
value=cls.FAVORITE_NODE_VALUE,
)
node.assets_amount = assets_amount
return node
def compute_node_from_and_assets_amount(self, user):
node_from, node = UserAssetGrantedTreeNodeRelation.get_node_from_with_node(
user, self.key
)
self.node_from = node_from
#
if node:
self.granted_assets_amount = node.node_assets_amount
def save(self):
""" 这是个只读 Model """
raise NotImplementedError
class PermedAsset(Asset):
class Meta:
proxy = True
verbose_name = _('Permed asset')
permissions = [
('view_myassets', _('Can view my assets')),
('view_userassets', _('Can view user assets')),
('view_usergroupassets', _('Can view usergroup assets')),
]
class PermedAccount(Account):
@lazyproperty
def actions(self):
return 0
class Meta:
proxy = True
verbose_name = _('Permed account')