mirror of
https://github.com/jumpserver/jumpserver.git
synced 2026-04-03 19:02:42 +00:00
* 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>
282 lines
11 KiB
Python
282 lines
11 KiB
Python
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()
|