From 63b338085ac7f9f67f298f97fa705c4819be206a Mon Sep 17 00:00:00 2001 From: halo Date: Thu, 14 Oct 2021 22:27:02 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BF=AE=E6=94=B9username=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C=EF=BC=8Ctelnet=E5=8D=8F=E8=AE=AE=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E8=BE=93=E5=85=A5=E4=B8=AD=E6=96=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../migrations/0012_auto_20211014_2209.py | 23 +++++++++++ .../migrations/0078_auto_20211014_2209.py | 38 +++++++++++++++++++ apps/assets/models/base.py | 2 +- apps/assets/serializers/domain.py | 2 + apps/assets/serializers/system_user.py | 14 +++++-- apps/common/validators.py | 5 ++- 6 files changed, 78 insertions(+), 6 deletions(-) create mode 100644 apps/applications/migrations/0012_auto_20211014_2209.py create mode 100644 apps/assets/migrations/0078_auto_20211014_2209.py diff --git a/apps/applications/migrations/0012_auto_20211014_2209.py b/apps/applications/migrations/0012_auto_20211014_2209.py new file mode 100644 index 000000000..3375f7399 --- /dev/null +++ b/apps/applications/migrations/0012_auto_20211014_2209.py @@ -0,0 +1,23 @@ +# Generated by Django 3.1.13 on 2021-10-14 14:09 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('applications', '0011_auto_20210826_1759'), + ] + + operations = [ + migrations.AlterField( + model_name='account', + name='username', + field=models.CharField(blank=True, db_index=True, max_length=128, verbose_name='Username'), + ), + migrations.AlterField( + model_name='historicalaccount', + name='username', + field=models.CharField(blank=True, db_index=True, max_length=128, verbose_name='Username'), + ), + ] diff --git a/apps/assets/migrations/0078_auto_20211014_2209.py b/apps/assets/migrations/0078_auto_20211014_2209.py new file mode 100644 index 000000000..b2c1cf371 --- /dev/null +++ b/apps/assets/migrations/0078_auto_20211014_2209.py @@ -0,0 +1,38 @@ +# Generated by Django 3.1.13 on 2021-10-14 14:09 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('assets', '0077_auto_20211012_1642'), + ] + + operations = [ + migrations.AlterField( + model_name='adminuser', + name='username', + field=models.CharField(blank=True, db_index=True, max_length=128, verbose_name='Username'), + ), + migrations.AlterField( + model_name='authbook', + name='username', + field=models.CharField(blank=True, db_index=True, max_length=128, verbose_name='Username'), + ), + migrations.AlterField( + model_name='gateway', + name='username', + field=models.CharField(blank=True, db_index=True, max_length=128, verbose_name='Username'), + ), + migrations.AlterField( + model_name='historicalauthbook', + name='username', + field=models.CharField(blank=True, db_index=True, max_length=128, verbose_name='Username'), + ), + migrations.AlterField( + model_name='systemuser', + name='username', + field=models.CharField(blank=True, db_index=True, max_length=128, verbose_name='Username'), + ), + ] diff --git a/apps/assets/models/base.py b/apps/assets/models/base.py index e13d228bd..d3ac5f493 100644 --- a/apps/assets/models/base.py +++ b/apps/assets/models/base.py @@ -173,7 +173,7 @@ class AuthMixin: class BaseUser(OrgModelMixin, AuthMixin): id = models.UUIDField(default=uuid.uuid4, primary_key=True) name = models.CharField(max_length=128, verbose_name=_('Name')) - username = models.CharField(max_length=128, blank=True, verbose_name=_('Username'), validators=[alphanumeric], db_index=True) + username = models.CharField(max_length=128, blank=True, verbose_name=_('Username'), db_index=True) password = fields.EncryptCharField(max_length=256, blank=True, null=True, verbose_name=_('Password')) private_key = fields.EncryptTextField(blank=True, null=True, verbose_name=_('SSH private key')) public_key = fields.EncryptTextField(blank=True, null=True, verbose_name=_('SSH public key')) diff --git a/apps/assets/serializers/domain.py b/apps/assets/serializers/domain.py index 60c69fb2b..172448d44 100644 --- a/apps/assets/serializers/domain.py +++ b/apps/assets/serializers/domain.py @@ -3,6 +3,7 @@ from rest_framework import serializers from django.utils.translation import ugettext_lazy as _ +from common.validators import alphanumeric from orgs.mixins.serializers import BulkOrgResourceModelSerializer from ..models import Domain, Gateway from .base import AuthSerializerMixin @@ -59,6 +60,7 @@ class GatewaySerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer): fields_fk = ['domain'] fields = fields_small + fields_fk extra_kwargs = { + 'username': {"validators": [alphanumeric]}, 'password': {'write_only': True}, 'private_key': {"write_only": True}, 'public_key': {"write_only": True}, diff --git a/apps/assets/serializers/system_user.py b/apps/assets/serializers/system_user.py index 7ffe51fa0..588aedfc4 100644 --- a/apps/assets/serializers/system_user.py +++ b/apps/assets/serializers/system_user.py @@ -4,6 +4,7 @@ from django.db.models import Count from common.mixins.serializers import BulkSerializerMixin from common.utils import ssh_pubkey_gen +from common.validators import alphanumeric_re, alphanumeric_cn_re from orgs.mixins.serializers import BulkOrgResourceModelSerializer from ..models import SystemUser, Asset from .utils import validate_password_contains_left_double_curly_bracket @@ -97,15 +98,20 @@ class SystemUserSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer): raise serializers.ValidationError(error) def validate_username(self, username): - if username: - return username - login_mode = self.get_initial_value("login_mode") protocol = self.get_initial_value("protocol") - username_same_with_user = self.get_initial_value("username_same_with_user") + if username: + regx = alphanumeric_re + if protocol == SystemUser.Protocol.telnet: + regx = alphanumeric_cn_re + if not regx.match(username): + raise serializers.ValidationError(_('Special char not allowed')) + return username + username_same_with_user = self.get_initial_value("username_same_with_user") if username_same_with_user: return '' + login_mode = self.get_initial_value("login_mode") if login_mode == SystemUser.LOGIN_AUTO and protocol != SystemUser.Protocol.vnc: msg = _('* Automatic login mode must fill in the username.') raise serializers.ValidationError(msg) diff --git a/apps/common/validators.py b/apps/common/validators.py index c22ea69da..8e7e504ed 100644 --- a/apps/common/validators.py +++ b/apps/common/validators.py @@ -11,9 +11,12 @@ from rest_framework import serializers from common.utils.strings import no_special_chars - alphanumeric = RegexValidator(r'^[0-9a-zA-Z_@\-\.]*$', _('Special char not allowed')) +alphanumeric_re = re.compile(r'^[0-9a-zA-Z_@\-\.]*$') + +alphanumeric_cn_re = re.compile(r'^[0-9a-zA-Z_@\-\.\u4E00-\u9FA5]*$') + class ProjectUniqueValidator(UniqueTogetherValidator): def __call__(self, attrs, serializer):