mirror of https://github.com/jumpserver/jumpserver
perf: Risk account
parent
39f266eb71
commit
3926d9ff46
|
@ -194,7 +194,8 @@ class CheckAccountManager(BaseManager):
|
||||||
|
|
||||||
now = timezone.now().isoformat()
|
now = timezone.now().isoformat()
|
||||||
for d in self.batch_risks:
|
for d in self.batch_risks:
|
||||||
key = f'{d["account"].asset_id}_{d["account"].username}_{d["risk"]}'
|
account = d["account"]
|
||||||
|
key = f'{account.asset_id}_{account.username}_{d["risk"]}'
|
||||||
origin_risk = ori_risk_map.get(key)
|
origin_risk = ori_risk_map.get(key)
|
||||||
|
|
||||||
if origin_risk and origin_risk.status != ConfirmOrIgnore.pending:
|
if origin_risk and origin_risk.status != ConfirmOrIgnore.pending:
|
||||||
|
@ -209,8 +210,9 @@ class CheckAccountManager(BaseManager):
|
||||||
update_risk(origin_risk)
|
update_risk(origin_risk)
|
||||||
else:
|
else:
|
||||||
create_risk({
|
create_risk({
|
||||||
"asset": d["account"].asset,
|
"account": account,
|
||||||
"username": d["account"].username,
|
"asset": account.asset,
|
||||||
|
"username": account.username,
|
||||||
"risk": d["risk"],
|
"risk": d["risk"],
|
||||||
"details": [{"datetime": now, 'type': 'init'}],
|
"details": [{"datetime": now, 'type': 'init'}],
|
||||||
})
|
})
|
||||||
|
|
|
@ -7,7 +7,7 @@ from django_filters import rest_framework as drf_filters
|
||||||
from assets.models import Node
|
from assets.models import Node
|
||||||
from common.drf.filters import BaseFilterSet
|
from common.drf.filters import BaseFilterSet
|
||||||
from common.utils.timezone import local_zero_hour, local_now
|
from common.utils.timezone import local_zero_hour, local_now
|
||||||
from .models import Account, GatheredAccount, ChangeSecretRecord, AccountRisk
|
from .models import Account, GatheredAccount, ChangeSecretRecord
|
||||||
|
|
||||||
|
|
||||||
class AccountFilterSet(BaseFilterSet):
|
class AccountFilterSet(BaseFilterSet):
|
||||||
|
@ -70,10 +70,7 @@ class AccountFilterSet(BaseFilterSet):
|
||||||
if not value:
|
if not value:
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
risks = AccountRisk.objects.filter(risk=value)
|
queryset = queryset.filter(risks__risk=value)
|
||||||
usernames = risks.values_list('username', flat=True)
|
|
||||||
assets = risks.values_list('asset', flat=True)
|
|
||||||
queryset = queryset.filter(username__in=usernames, asset__in=assets)
|
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models import Exists, OuterRef
|
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from simple_history.models import HistoricalRecords
|
from simple_history.models import HistoricalRecords
|
||||||
|
|
||||||
|
@ -169,20 +168,14 @@ class Account(AbsConnectivity, LabeledMixin, BaseAccount):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_risks(cls, queryset=None, risk_type=None):
|
def get_risks(cls, queryset=None, risk_type=None):
|
||||||
# TODO 数据量大时,子查询性能不佳,考虑用原生sql或者在模型层面做出改动
|
query = {
|
||||||
from accounts.models import AccountRisk
|
'risks__risk': risk_type
|
||||||
subquery = AccountRisk.objects.filter(
|
}
|
||||||
asset_id=OuterRef('asset_id'),
|
|
||||||
username=OuterRef('username')
|
|
||||||
)
|
|
||||||
|
|
||||||
if risk_type:
|
|
||||||
subquery = subquery.filter(risk=risk_type)
|
|
||||||
|
|
||||||
if queryset is None:
|
if queryset is None:
|
||||||
queryset = cls.objects.all()
|
queryset = cls.objects.all()
|
||||||
|
|
||||||
return queryset.filter(Exists(subquery))
|
return queryset.filter(**query)
|
||||||
|
|
||||||
|
|
||||||
def replace_history_model_with_mixin():
|
def replace_history_model_with_mixin():
|
||||||
|
|
|
@ -58,14 +58,19 @@ class RiskChoice(TextChoices):
|
||||||
|
|
||||||
|
|
||||||
class AccountRisk(JMSOrgBaseModel):
|
class AccountRisk(JMSOrgBaseModel):
|
||||||
asset = models.ForeignKey('assets.Asset', on_delete=models.CASCADE, related_name='risks', verbose_name=_('Asset'))
|
asset = models.ForeignKey(
|
||||||
|
'assets.Asset', on_delete=models.CASCADE, related_name='risks', verbose_name=_('Asset')
|
||||||
|
)
|
||||||
|
account = models.ForeignKey(
|
||||||
|
'accounts.Account', on_delete=models.CASCADE, related_name='risks', verbose_name=_('Account'), null=True
|
||||||
|
)
|
||||||
|
status = models.CharField(
|
||||||
|
max_length=32, choices=ConfirmOrIgnore.choices,
|
||||||
|
default=ConfirmOrIgnore.pending, blank=True, verbose_name=_('Status')
|
||||||
|
)
|
||||||
username = models.CharField(max_length=32, verbose_name=_('Username'))
|
username = models.CharField(max_length=32, verbose_name=_('Username'))
|
||||||
account = models.ForeignKey('accounts.Account', on_delete=models.CASCADE, related_name='risks',
|
|
||||||
verbose_name=_('Account'), null=True)
|
|
||||||
risk = models.CharField(max_length=128, verbose_name=_('Risk'), choices=RiskChoice.choices)
|
|
||||||
status = models.CharField(max_length=32, choices=ConfirmOrIgnore.choices, default=ConfirmOrIgnore.pending,
|
|
||||||
blank=True, verbose_name=_('Status'))
|
|
||||||
details = models.JSONField(default=list, verbose_name=_('Details'))
|
details = models.JSONField(default=list, verbose_name=_('Details'))
|
||||||
|
risk = models.CharField(max_length=128, verbose_name=_('Risk'), choices=RiskChoice.choices)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _('Account risk')
|
verbose_name = _('Account risk')
|
||||||
|
|
Loading…
Reference in New Issue