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): + protocol = self.get_initial_value("protocol") 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 - 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") + 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):