mirror of https://github.com/jumpserver/jumpserver
perf: check account engine
parent
01ac001f84
commit
ef0df85a15
|
@ -138,47 +138,16 @@ class CheckAccountEngineViewSet(JMSModelViewSet):
|
||||||
search_fields = ("name",)
|
search_fields = ("name",)
|
||||||
serializer_class = serializers.CheckAccountEngineSerializer
|
serializer_class = serializers.CheckAccountEngineSerializer
|
||||||
|
|
||||||
@staticmethod
|
perm_model = CheckAccountEngine
|
||||||
def get_default_engines():
|
|
||||||
data = [
|
|
||||||
{
|
|
||||||
"id": "00000000-0000-0000-0000-000000000001",
|
|
||||||
"slug": "check_gathered_account",
|
|
||||||
"name": "检查发现的账号",
|
|
||||||
"comment": "基于自动发现的账号结果进行检查分析,检查 用户组、公钥、sudoers 等信息",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "00000000-0000-0000-0000-000000000002",
|
|
||||||
"slug": "check_account_secret",
|
|
||||||
"name": "检查账号密码强弱",
|
|
||||||
"comment": "基于账号密码的安全性进行检查分析, 检查密码强度、泄露等信息",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "00000000-0000-0000-0000-000000000003",
|
|
||||||
"slug": "check_account_repeat",
|
|
||||||
"name": "检查账号密码是否重复",
|
|
||||||
"comment": "检查账号是否与其它账号相同"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "00000000-0000-0000-0000-000000000004",
|
|
||||||
"slug": "check_account_leak",
|
|
||||||
"name": "检查账号密码是否是常见密码",
|
|
||||||
"comment": "检查账号密码是否是常见泄露的密码"
|
|
||||||
},
|
|
||||||
]
|
|
||||||
return data
|
|
||||||
|
|
||||||
def init_if_need(self):
|
|
||||||
data = self.get_default_engines()
|
|
||||||
model_cls = CheckAccountEngine
|
|
||||||
|
|
||||||
if model_cls.objects.count() == 4:
|
|
||||||
return
|
|
||||||
|
|
||||||
for item in data:
|
|
||||||
model_cls.objects.update_or_create(defaults=item, id=item["id"])
|
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
# return self.get_default_engines()
|
return CheckAccountEngine.get_default_engines()
|
||||||
self.init_if_need()
|
|
||||||
return CheckAccountEngine.objects.all()
|
def filter_queryset(self, queryset: list):
|
||||||
|
search = self.request.GET.get('search')
|
||||||
|
if search is not None:
|
||||||
|
queryset = [
|
||||||
|
item for item in queryset
|
||||||
|
if search in item['name']
|
||||||
|
]
|
||||||
|
return queryset
|
||||||
|
|
|
@ -6,28 +6,7 @@ import django.db.models.deletion
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
def init_account_check_engine(apps, schema_editor):
|
|
||||||
data = [
|
|
||||||
{
|
|
||||||
'id': '00000000-0000-0000-0000-000000000001',
|
|
||||||
'slug': 'check_gathered_account',
|
|
||||||
'name': '检查发现的账号',
|
|
||||||
'comment': '基于自动发现的账号结果进行检查分析,检查 用户组、公钥、sudoers 等信息'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'id': '00000000-0000-0000-0000-000000000002',
|
|
||||||
'slug': 'check_account_secret',
|
|
||||||
'name': '检查账号密码强弱',
|
|
||||||
'comment': '基于账号密码的安全性进行检查分析, 检查密码强度、泄露等信息'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
model_cls = apps.get_model('accounts', 'CheckAccountEngine')
|
|
||||||
for item in data:
|
|
||||||
model_cls.objects.create(**item)
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
("assets", "0007_baseautomation_date_last_run_and_more"),
|
("assets", "0007_baseautomation_date_last_run_and_more"),
|
||||||
(
|
(
|
||||||
|
@ -139,5 +118,4 @@ class Migration(migrations.Migration):
|
||||||
verbose_name="Engines",
|
verbose_name="Engines",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
migrations.RunPython(init_account_check_engine),
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
# Generated by Django 4.1.13 on 2025-01-21 08:41
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('accounts', '0027_accountrisk_gathered_account'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='checkaccountengine',
|
||||||
|
name='is_active',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='checkaccountautomation',
|
||||||
|
name='engines',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='checkaccountautomation',
|
||||||
|
name='engines',
|
||||||
|
field=models.JSONField(default=list, verbose_name='Engines'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -15,13 +15,13 @@ __all__ = ['CheckAccountAutomation', 'AccountRisk', 'RiskChoice', 'CheckAccountE
|
||||||
|
|
||||||
|
|
||||||
class CheckAccountAutomation(AccountBaseAutomation):
|
class CheckAccountAutomation(AccountBaseAutomation):
|
||||||
engines = models.ManyToManyField('CheckAccountEngine', related_name='check_automations', verbose_name=_('Engines'))
|
engines = models.JSONField(default=list, verbose_name=_('Engines'))
|
||||||
recipients = models.ManyToManyField('users.User', verbose_name=_("Recipient"), blank=True)
|
recipients = models.ManyToManyField('users.User', verbose_name=_("Recipient"), blank=True)
|
||||||
|
|
||||||
def to_attr_json(self):
|
def to_attr_json(self):
|
||||||
attr_json = super().to_attr_json()
|
attr_json = super().to_attr_json()
|
||||||
attr_json.update({
|
attr_json.update({
|
||||||
'engines': [engine.slug for engine in self.engines.all()],
|
'engines': self.engines,
|
||||||
'recipients': [str(user.id) for user in self.recipients.all()]
|
'recipients': [str(user.id) for user in self.recipients.all()]
|
||||||
})
|
})
|
||||||
return attr_json
|
return attr_json
|
||||||
|
@ -117,14 +117,43 @@ class AccountRisk(JMSOrgBaseModel):
|
||||||
|
|
||||||
class CheckAccountEngine(JMSBaseModel):
|
class CheckAccountEngine(JMSBaseModel):
|
||||||
name = models.CharField(max_length=128, verbose_name=_('Name'), unique=True)
|
name = models.CharField(max_length=128, verbose_name=_('Name'), unique=True)
|
||||||
slug = models.SlugField(max_length=128, verbose_name=_('Slug'), unique=True) #
|
slug = models.SlugField(max_length=128, verbose_name=_('Slug'), unique=True)
|
||||||
is_active = models.BooleanField(default=True, verbose_name=_('Is active'))
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
def internals(self):
|
@staticmethod
|
||||||
return [
|
def get_default_engines():
|
||||||
'check_gathered_account',
|
data = [
|
||||||
'check_account_secret'
|
{
|
||||||
|
"id": "00000000-0000-0000-0000-000000000001",
|
||||||
|
"slug": "check_gathered_account",
|
||||||
|
"name": _("Check the discovered accounts"),
|
||||||
|
"comment": _(
|
||||||
|
"Perform checks and analyses based on automatically discovered account results, "
|
||||||
|
"including user groups, public keys, sudoers, and other information"
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "00000000-0000-0000-0000-000000000002",
|
||||||
|
"slug": "check_account_secret",
|
||||||
|
"name": _("Check the strength of your account and password"),
|
||||||
|
"comment": _(
|
||||||
|
"Perform checks and analyses based on the security of account passwords, "
|
||||||
|
"including password strength, leakage, etc."
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "00000000-0000-0000-0000-000000000003",
|
||||||
|
"slug": "check_account_repeat",
|
||||||
|
"name": _("Check if the account and password are repeated"),
|
||||||
|
"comment": _("Check if the account is the same as other accounts")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "00000000-0000-0000-0000-000000000004",
|
||||||
|
"slug": "check_account_leak",
|
||||||
|
"name": _("Check whether the account password is a common password"),
|
||||||
|
"comment": _("Check whether the account password is a commonly leaked password")
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
return data
|
||||||
|
|
|
@ -10,12 +10,12 @@ from accounts.models import (
|
||||||
RiskChoice,
|
RiskChoice,
|
||||||
CheckAccountEngine,
|
CheckAccountEngine,
|
||||||
)
|
)
|
||||||
|
from accounts.risk_handlers import TYPE_CHOICES
|
||||||
from assets.models import Asset
|
from assets.models import Asset
|
||||||
from common.const import ConfirmOrIgnore
|
from common.const import ConfirmOrIgnore
|
||||||
from common.serializers.fields import ObjectRelatedField, LabeledChoiceField
|
from common.serializers.fields import ObjectRelatedField, LabeledChoiceField
|
||||||
from common.utils import get_logger
|
from common.utils import get_logger
|
||||||
from .base import BaseAutomationSerializer
|
from .base import BaseAutomationSerializer
|
||||||
from accounts.risk_handlers import TYPE_CHOICES
|
|
||||||
|
|
||||||
logger = get_logger(__file__)
|
logger = get_logger(__file__)
|
||||||
|
|
||||||
|
@ -88,9 +88,9 @@ class CheckAccountAutomationSerializer(BaseAutomationSerializer):
|
||||||
model = CheckAccountAutomation
|
model = CheckAccountAutomation
|
||||||
read_only_fields = BaseAutomationSerializer.Meta.read_only_fields
|
read_only_fields = BaseAutomationSerializer.Meta.read_only_fields
|
||||||
fields = (
|
fields = (
|
||||||
BaseAutomationSerializer.Meta.fields
|
BaseAutomationSerializer.Meta.fields
|
||||||
+ ["engines", "recipients"]
|
+ ["engines", "recipients"]
|
||||||
+ read_only_fields
|
+ read_only_fields
|
||||||
)
|
)
|
||||||
extra_kwargs = BaseAutomationSerializer.Meta.extra_kwargs
|
extra_kwargs = BaseAutomationSerializer.Meta.extra_kwargs
|
||||||
|
|
||||||
|
@ -98,12 +98,18 @@ class CheckAccountAutomationSerializer(BaseAutomationSerializer):
|
||||||
def model_type(self):
|
def model_type(self):
|
||||||
return AutomationTypes.check_account
|
return AutomationTypes.check_account
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def validate_engines(engines):
|
||||||
|
valid_slugs = {i['slug'] for i in CheckAccountEngine.get_default_engines()}
|
||||||
|
|
||||||
|
if not all(engine in valid_slugs for engine in engines):
|
||||||
|
raise serializers.ValidationError(_("Invalid engine id"))
|
||||||
|
|
||||||
|
return engines
|
||||||
|
|
||||||
|
|
||||||
class CheckAccountEngineSerializer(serializers.ModelSerializer):
|
class CheckAccountEngineSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = CheckAccountEngine
|
model = CheckAccountEngine
|
||||||
fields = ["id", "name", "slug", "is_active", "comment"]
|
fields = ["id", "name", "slug", "comment"]
|
||||||
read_only_fields = ["slug"]
|
read_only_fields = ["slug"]
|
||||||
extra_kwargs = {
|
|
||||||
"is_active": {"required": False},
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue