Files
jumpserver/apps/assets/serializers/platform.py
fit2bot 3f4141ca0b merge: with pam (#14911)
* perf: change i18n

* perf: pam

* perf: change translate

* perf: add check account

* perf: add date field

* perf: add account filter

* perf: remove some js

* perf: add account status action

* perf: update pam

* perf: 修改 discover account

* perf: update filter

* perf: update gathered account

* perf: 修改账号同步

* perf: squash migrations

* perf: update pam

* perf: change i18n

* perf: update account risk

* perf: 更新风险发现

* perf: remove css

* perf: Admin connection token

* perf: Add a switch to check connectivity after changing the password, and add a custom ssh command for push tasks

* perf: Modify account migration files

* perf: update pam

* perf: remove to check account dir

* perf: Admin connection token

* perf: update check account

* perf: 优化发送结果

* perf: update pam

* perf: update bulk update create

* perf: prepaire using thread timer for bulk_create_decorator

* perf: update bulk create decorator

* perf: 优化 playbook manager

* perf: 优化收集账号的报表

* perf: Update poetry

* perf: Update Dockerfile with new base image tag

* fix: Account migrate 0012 file

* perf: 修改备份

* perf: update pam

* fix: Expand resource_type filter to include raw type

* feat: PAM Service (#14552)

* feat: PAM Service

* perf: import package name

---------

Co-authored-by: jiangweidong <1053570670@qq.com>

* perf: Change secret dashboard (#14551)

Co-authored-by: feng <1304903146@qq.com>

* perf: update migrations

* perf: 修改支持 pam

* perf: Change secret record table dashboard

* perf: update status

* fix: Automation send report

* perf: Change secret report

* feat: windows accounts gather

* perf: update change status

* perf: Account backup

* perf: Account backup report

* perf: Account migrate

* perf: update service to application

* perf: update migrations

* perf: update logo

* feat: oracle accounts gather (#14571)

* feat: oracle accounts gather

* feat: sqlserver accounts gather

* feat: postgresql accounts gather

* feat: mysql accounts gather

---------

Co-authored-by: wangruidong <940853815@qq.com>

* feat: mongodb accounts gather

* perf: Change secret

* perf: Migrate

* perf: Merge conflicting migration files

* perf: Change secret

* perf: Automation filter org

* perf: Account push

* perf: Random secret string

* perf: Enhance SQL query and update risk handling in accounts

* perf: Ticket filter assignee_id

* perf: 修改 account remote

* perf: 修改一些 adhoc 任务

* perf: Change secret

* perf: Remove push account extra api

* perf: update status

* perf: The entire organization can view activity log

* fix: risk field check

* perf: add account details api

* perf: add demo mode

* perf: Delete gather_account

* perf: Perfect solution to account version problem

* perf: Update status action to handle multiple accounts

* perf: Add GatherAccountDetailField and update serializers

* perf: Display account history in combination with password change records

* perf: Lina translate

* fix: Update mysql_filter to handle nested user info

* perf: Admin connection token validate_permission account

* perf: copy move account

* perf: account filter risk

* perf: account risk filter

* perf: Copy move account failed message

* fix: gather account sync account to asset

* perf: Pam dashboard

* perf: Account dashboard total accounts

* perf: Pam dashboard

* perf: Change secret filter account secret_reset

* perf: 修改 risk filter

* perf: pam translate

* feat: Check for leaked duplicate passwords. (#14711)

* feat: Check for leaked duplicate passwords.

* perf: Use SQLite instead of txt as leak password database

---------

Co-authored-by: jiangweidong <1053570670@qq.com>
Co-authored-by: 老广 <ibuler@qq.com>

* perf: merge with remote

* perf: Add risk change_password_add handle

* perf: Pam dashboard

* perf: check account manager import

* perf: 重构扫描

* perf: 修改 db

* perf: Gather account manager

* perf: update change db lib

* perf: dashboard

* perf: Account gather

* perf: 修改 asset get queryset

* perf: automation report

* perf: Pam account

* perf: Pam dashboard api

* perf: risk add account

* perf: 修改 risk check

* perf: Risk account

* perf: update risk add reopen action

* perf: add pylintrc

* Revert "perf: automation report"

This reverts commit 22aee54207.

* perf: check account engine

* perf: Perf: Optimism Gather Report Style

* Perf: Remove unuser actions

* Perf: Perf push account

* perf: perf gather account

* perf: Automation report

* perf: Push account recorder

* perf: Push account record

* perf: Pam dashboard

* perf: perf

* perf: update intergration

* perf: integrations application detail add account tab page

* feat: Custom change password supports configuration of interactive items

* perf: Go and Python demo code

* perf: Custom secret change

* perf: add user filter

* perf: translate

* perf: Add demo code docs

* perf: update some i18n

* perf: update some i18n

* perf: Add Java, Node, Go, and cURL demo code

* perf: Translate

* perf: Change secret translate

* perf: Translate

* perf: update some i18n

* perf: translate

* perf: Ansible playbook

* perf: update some choice

* perf: update some choice

* perf: update account serializer remote unused code

* perf: conflict

* perf: update import

---------

Co-authored-by: ibuler <ibuler@qq.com>
Co-authored-by: feng <1304903146@qq.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: wangruidong <940853815@qq.com>
Co-authored-by: jiangweidong <1053570670@qq.com>
Co-authored-by: feng626 <57284900+feng626@users.noreply.github.com>
Co-authored-by: zhaojisen <1301338853@qq.com>
2025-02-21 16:39:57 +08:00

282 lines
11 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from django.db.models import QuerySet
from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from rest_framework.validators import UniqueValidator
from assets.models import Asset
from common.serializers import (
WritableNestedModelSerializer, type_field_map, MethodSerializer,
DictSerializer, create_serializer_class, ResourceLabelsMixin,
CommonSerializerMixin
)
from common.serializers.fields import LabeledChoiceField, ObjectRelatedField
from common.utils import lazyproperty
from ..const import Category, AllTypes, Protocol, SuMethodChoices
from ..models import Platform, PlatformProtocol, PlatformAutomation
__all__ = ["PlatformSerializer", "PlatformOpsMethodSerializer", "PlatformProtocolSerializer", "PlatformListSerializer"]
class PlatformAutomationSerializer(serializers.ModelSerializer):
class Meta:
model = PlatformAutomation
fields = [
"id",
"ansible_enabled", "ansible_config",
"ping_enabled", "ping_method", "ping_params",
"push_account_enabled", "push_account_method", "push_account_params",
"gather_facts_enabled", "gather_facts_method", "gather_facts_params",
"change_secret_enabled", "change_secret_method", "change_secret_params",
"verify_account_enabled", "verify_account_method", "verify_account_params",
"gather_accounts_enabled", "gather_accounts_method", "gather_accounts_params",
"remove_account_enabled", "remove_account_method", "remove_account_params",
]
extra_kwargs = {
# 启用资产探测
"ping_enabled": {"label": _("Ping enabled"), "help_text": _("Enable asset detection")},
"ping_method": {"label": _("Ping method")},
"gather_facts_enabled": {
"label": _("Gather facts enabled"),
"help_text": _("Enable asset information collection")
},
"gather_facts_method": {
"label": _("Gather facts method"),
},
"verify_account_enabled": {
"label": _("Verify account enabled"),
"help_text": _("Enable account verification")
},
"verify_account_method": {
"label": _("Verify account method"),
},
"change_secret_enabled": {
"label": _("Change secret enabled"),
"help_text": _("Enable account secret auto change")
},
"change_secret_method": {
"label": _("Change secret method"),
},
"push_account_enabled": {
"label": _("Push account enabled"),
"help_text": _("Enable account auto push")
},
"push_account_method": {
"label": _("Push account method"),
},
"gather_accounts_enabled": {
"label": _("Gather accounts enabled"),
"help_text": _("Enable account collection")
},
"gather_accounts_method": {
"label": _("Gather accounts method"),
},
"remove_account_method": {
"label": _("Remove account method"),
},
"remove_account_enabled": {
"label": _("Remove accounts enabled"),
"help_text": _("Enable account remove"),
},
}
class PlatformProtocolSerializer(serializers.ModelSerializer):
setting = MethodSerializer(required=False, label=_("Setting"))
port_from_addr = serializers.BooleanField(label=_("Port from addr"), read_only=True)
class Meta:
model = PlatformProtocol
fields = [
"id", "name", "port", "port_from_addr",
"primary", "required", "default", "public",
"secret_types", "setting",
]
extra_kwargs = {
"primary": {
"help_text": _(
"This protocol is primary, and it must be set when adding assets. "
"Additionally, there can only be one primary protocol."
)
},
"required": {
"help_text": _("This protocol is required, and it must be set when adding assets.")
},
"default": {
"help_text": _("This protocol is default, when adding assets, it will be displayed by default.")
},
"public": {
"help_text": _("This protocol is public, asset will show this protocol to user")
},
}
def get_setting_serializer(self):
request = self.context.get('request')
default_field = DictSerializer(required=False)
if not request:
return default_field
if self.instance and isinstance(self.instance, (QuerySet, list)):
instance = self.instance[0]
else:
instance = self.instance
protocol = request.query_params.get('name', '')
if instance and not protocol:
protocol = instance.name
protocol_settings = Protocol.settings()
setting_fields = protocol_settings.get(protocol, {}).get('setting')
if not setting_fields:
return default_field
setting_fields = [{'name': k, **v} for k, v in setting_fields.items()]
name = '{}ProtocolSettingSerializer'.format(protocol.capitalize())
return create_serializer_class(name, setting_fields)()
def validate(self, cleaned_data):
name = cleaned_data.get('name')
if name in ['winrm']:
cleaned_data['public'] = False
return cleaned_data
def to_file_representation(self, data):
return '{name}/{port}'.format(**data)
def to_file_internal_value(self, data):
name, port = data.split('/')
return {'name': name, 'port': port}
@staticmethod
def get_render_help_text():
return _('Protocols, format is ["protocol/port"]')
class PlatformCustomField(serializers.Serializer):
TYPE_CHOICES = [(t, t) for t, c in type_field_map.items()]
name = serializers.CharField(label=_("Name"), max_length=128)
label = serializers.CharField(label=_("Label"), max_length=128)
type = serializers.ChoiceField(choices=TYPE_CHOICES, label=_("Type"), default='str')
default = serializers.CharField(default="", allow_blank=True, label=_("Default"), max_length=1024)
help_text = serializers.CharField(default="", allow_blank=True, label=_("Help text"), max_length=1024)
choices = serializers.ListField(default=list, label=_("Choices"), required=False)
class PlatformSerializer(ResourceLabelsMixin, CommonSerializerMixin, WritableNestedModelSerializer):
id = serializers.IntegerField(
label='ID', required=False,
validators=[UniqueValidator(queryset=Platform.objects.all())]
)
charset = LabeledChoiceField(choices=Platform.CharsetChoices.choices, label=_("Charset"), default='utf-8')
type = LabeledChoiceField(choices=AllTypes.choices(), label=_("Type"))
category = LabeledChoiceField(choices=Category.choices, label=_("Category"))
protocols = PlatformProtocolSerializer(label=_("Protocols"), many=True, required=False)
automation = PlatformAutomationSerializer(label=_("Automation"), required=False, default=dict)
su_method = LabeledChoiceField(
choices=SuMethodChoices.choices, label=_("Su method"),
required=False, default=SuMethodChoices.sudo, allow_null=True
)
custom_fields = PlatformCustomField(label=_("Custom fields"), many=True, required=False)
assets = ObjectRelatedField(queryset=Asset.objects, many=True, required=False, label=_('Assets'))
assets_amount = serializers.IntegerField(label=_('Assets amount'), read_only=True)
class Meta:
model = Platform
fields_mini = ["id", "name", "internal"]
fields_small = fields_mini + [
"category", "type", "charset",
]
fields_unexport = ['automation']
read_only_fields = [
'internal', 'date_created', 'date_updated',
'created_by', 'updated_by'
]
fields_m2m = ['assets', 'assets_amount']
fields = fields_small + fields_m2m + [
"protocols", "domain_enabled", "su_enabled", "su_method",
"automation", "comment", "custom_fields", "labels"
] + read_only_fields
extra_kwargs = {
"su_enabled": {
"label": _('Su enabled'),
"help_text": _(
"Login with account when accessing assets, then automatically switch to another, "
"similar to logging in with a regular account and then switching to root"
)
},
"domain_enabled": {
"label": _('Gateway enabled'),
"help_text": _("Assets can be connected using a zone gateway")
},
"domain_default": {"label": _('Default Domain')},
'assets': {'required': False, 'label': _('Assets')},
}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.set_initial_value()
def set_initial_value(self):
if not hasattr(self, 'initial_data'):
return
if self.instance:
return
if not self.initial_data.get('automation'):
self.initial_data['automation'] = {}
@property
def platform_category_type(self):
if self.instance:
return self.instance.category, self.instance.type
if self.initial_data:
return self.initial_data.get('category'), self.initial_data.get('type')
raise serializers.ValidationError({'type': _("type is required")})
def add_type_choices(self, name, label):
tp = self.fields['type']
tp.choices[name] = label
tp.choice_strings_to_values[name] = label
@lazyproperty
def constraints(self):
category, tp = self.platform_category_type
constraints = AllTypes.get_constraints(category, tp)
return constraints
def validate_protocols(self, protocols):
if not protocols:
raise serializers.ValidationError(_("Protocols is required"))
primary = [p for p in protocols if p.get('primary')]
if not primary:
protocols[0]['primary'] = True
# 这里不设置不行write_nested 不使用 validated 中的
self.initial_data['protocols'] = protocols
return protocols
def validate_su_enabled(self, su_enabled):
return su_enabled and self.constraints.get('su_enabled', False)
def validate_domain_enabled(self, domain_enabled):
return domain_enabled and self.constraints.get('domain_enabled', False)
def validate_automation(self, automation):
automation = automation or {}
ansible_enabled = automation.get('ansible_enabled', False) \
and self.constraints['automation'].get('ansible_enabled', False)
automation['ansible_enable'] = ansible_enabled
return automation
class PlatformListSerializer(PlatformSerializer):
class Meta(PlatformSerializer.Meta):
fields = list(set(PlatformSerializer.Meta.fields + ['assets_amount']) - {'assets'})
class PlatformOpsMethodSerializer(serializers.Serializer):
id = serializers.CharField(read_only=True)
name = serializers.CharField(max_length=50, label=_("Name"))
category = serializers.CharField(max_length=50, label=_("Category"))
type = serializers.ListSerializer(child=serializers.CharField())
method = serializers.CharField()