From 200470c9556279fe4485dd2b500845bf6b869e4f Mon Sep 17 00:00:00 2001 From: nero Date: Tue, 12 Dec 2023 10:40:43 +0800 Subject: [PATCH 1/6] =?UTF-8?q?feat:=20=E9=99=90=E5=88=B6logo=E5=A4=A7?= =?UTF-8?q?=E5=B0=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data_source_organization/serializers.py | 17 ++++++++++++++--- .../apis/web/personal_center/serializers.py | 3 ++- .../bkuser/apis/web/tenant/serializers.py | 16 +++++++++++++--- src/bk-user/bkuser/biz/validators.py | 18 ++++++++++++++++++ src/bk-user/bkuser/settings.py | 3 +++ 5 files changed, 50 insertions(+), 7 deletions(-) diff --git a/src/bk-user/bkuser/apis/web/data_source_organization/serializers.py b/src/bk-user/bkuser/apis/web/data_source_organization/serializers.py index 240e79e7e..37321bfe8 100644 --- a/src/bk-user/bkuser/apis/web/data_source_organization/serializers.py +++ b/src/bk-user/bkuser/apis/web/data_source_organization/serializers.py @@ -25,7 +25,7 @@ ) from bkuser.apps.tenant.constants import UserFieldDataType from bkuser.apps.tenant.models import TenantUserCustomField -from bkuser.biz.validators import validate_data_source_user_username +from bkuser.biz.validators import validate_data_source_user_username, validate_logo from bkuser.common.validators import validate_phone_with_country_code logger = logging.getLogger(__name__) @@ -154,7 +154,12 @@ class UserCreateInputSLZ(serializers.Serializer): help_text="手机号国际区号", required=False, default=settings.DEFAULT_PHONE_COUNTRY_CODE ) phone = serializers.CharField(help_text="手机号") - logo = serializers.CharField(help_text="用户 Logo", required=False, default=settings.DEFAULT_DATA_SOURCE_USER_LOGO) + logo = serializers.CharField( + help_text="用户 Logo", + required=False, + default=settings.DEFAULT_DATA_SOURCE_USER_LOGO, + validators=[validate_logo], + ) extras = serializers.JSONField(help_text="自定义字段", default=dict) department_ids = serializers.ListField(help_text="部门ID列表", child=serializers.IntegerField(), default=[]) @@ -258,7 +263,13 @@ class UserUpdateInputSLZ(serializers.Serializer): email = serializers.CharField(help_text="邮箱") phone_country_code = serializers.CharField(help_text="手机国际区号") phone = serializers.CharField(help_text="手机号") - logo = serializers.CharField(help_text="用户 Logo", allow_blank=True, required=False, default="") + logo = serializers.CharField( + help_text="用户 Logo", + allow_blank=True, + required=False, + default=settings.DEFAULT_DATA_SOURCE_USER_LOGO, + validators=[validate_logo], + ) extras = serializers.JSONField(help_text="自定义字段") department_ids = serializers.ListField(help_text="部门ID列表", child=serializers.IntegerField()) diff --git a/src/bk-user/bkuser/apis/web/personal_center/serializers.py b/src/bk-user/bkuser/apis/web/personal_center/serializers.py index b66783bbe..eaea3311b 100644 --- a/src/bk-user/bkuser/apis/web/personal_center/serializers.py +++ b/src/bk-user/bkuser/apis/web/personal_center/serializers.py @@ -19,6 +19,7 @@ from bkuser.apis.web.organization.serializers import TenantUserDepartmentOutputSLZ, TenantUserLeaderOutputSLZ from bkuser.apps.tenant.models import TenantUser from bkuser.biz.tenant import TenantUserHandler +from bkuser.biz.validators import validate_logo from bkuser.common.validators import validate_phone_with_country_code @@ -145,4 +146,4 @@ def validate(self, attrs): class TenantUserLogoUpdateInputSLZ(serializers.Serializer): - logo = serializers.CharField(help_text="用户 Logo") + logo = serializers.CharField(help_text="用户 Logo", validators=[validate_logo]) diff --git a/src/bk-user/bkuser/apis/web/tenant/serializers.py b/src/bk-user/bkuser/apis/web/tenant/serializers.py index 7c6dd4485..631646922 100644 --- a/src/bk-user/bkuser/apis/web/tenant/serializers.py +++ b/src/bk-user/bkuser/apis/web/tenant/serializers.py @@ -23,7 +23,7 @@ from bkuser.apps.tenant.models import Tenant, TenantUser from bkuser.biz.data_source import DataSourceSimpleInfo from bkuser.biz.tenant import TenantUserWithInheritedInfo -from bkuser.biz.validators import validate_data_source_user_username +from bkuser.biz.validators import validate_data_source_user_username, validate_logo from bkuser.common.passwd import PasswordValidator from bkuser.plugins.base import get_default_plugin_cfg from bkuser.plugins.constants import DataSourcePluginEnum @@ -83,7 +83,13 @@ def validate_notification(self, notification: Dict[str, Any]) -> Dict[str, Any]: class TenantCreateInputSLZ(serializers.Serializer): id = serializers.CharField(help_text="租户 ID") name = serializers.CharField(help_text="租户名称") - logo = serializers.CharField(help_text="租户 Logo", required=False, allow_blank=True, default="") + logo = serializers.CharField( + help_text="租户 Logo", + required=False, + allow_blank=True, + default=settings.DEFAULT_TENANT_LOGO, + validators=[validate_logo], + ) managers = serializers.ListField(help_text="管理人列表", child=TenantManagerCreateInputSLZ(), allow_empty=False) feature_flags = TenantFeatureFlagSLZ(help_text="租户特性集") password_initial_config = TenantManagerPasswordInitialConfigSLZ() @@ -161,7 +167,11 @@ def get_data_sources(self, obj: Tenant) -> List[Dict]: class TenantUpdateInputSLZ(serializers.Serializer): name = serializers.CharField(help_text="租户名称") logo = serializers.CharField( - help_text="租户 Logo", required=False, allow_blank=True, default=settings.DEFAULT_TENANT_LOGO + help_text="租户 Logo", + required=False, + allow_blank=True, + default=settings.DEFAULT_TENANT_LOGO, + validators=[validate_logo], ) manager_ids = serializers.ListField(child=serializers.CharField(), help_text="租户用户 ID 列表", allow_empty=False) feature_flags = TenantFeatureFlagSLZ(help_text="租户特性集") diff --git a/src/bk-user/bkuser/biz/validators.py b/src/bk-user/bkuser/biz/validators.py index 50a648d8a..b91927f67 100644 --- a/src/bk-user/bkuser/biz/validators.py +++ b/src/bk-user/bkuser/biz/validators.py @@ -8,9 +8,11 @@ an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. """ +import base64 import logging import re +from django.conf import settings from django.utils.translation import gettext_lazy as _ from rest_framework.exceptions import ValidationError @@ -36,3 +38,19 @@ def validate_tenant_custom_field_name(value): "{} 不符合 自定义字段 的命名规范: 由3-32位字母、数字、下划线(_)字符组成,以字母开头,字母或数字结尾" # noqa: E501 ).format(value), ) + + +def validate_logo(value): + if not value: + return + + try: + decoded_data = base64.b64decode(value) + except Exception: + # Decoding failed or invalid Base64-encoded image + logger.exception("invalid image") + raise ValidationError(_("无效logo文件")) + + # Check if the size exceeds the specified limit + if len(decoded_data) / 1024 > settings.MAX_LOGO_SIZE: + raise ValidationError(_("logo 文件大小超过限制{}KB").format(settings.MAX_LOGO_SIZE)) diff --git a/src/bk-user/bkuser/settings.py b/src/bk-user/bkuser/settings.py index 8fbb43855..2cc77a085 100644 --- a/src/bk-user/bkuser/settings.py +++ b/src/bk-user/bkuser/settings.py @@ -517,6 +517,9 @@ # ------------------------------------------ 业务逻辑配置 ------------------------------------------ +# logo文件大小限制,单位为: KB +MAX_LOGO_SIZE = env.int("MAX_LOGO_SIZE", 256) + # 数据源插件默认Logo,值为base64格式图片数据 DEFAULT_DATA_SOURCE_PLUGIN_LOGO = "" # 租户默认Logo,值为base64格式图片数据 From c4ec2a789fd3696fe301938bbf4436143b1d78d9 Mon Sep 17 00:00:00 2001 From: nero Date: Fri, 15 Dec 2023 13:53:43 +0800 Subject: [PATCH 2/6] =?UTF-8?q?refactor:=20cr=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/bk-user/bkuser/biz/validators.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bk-user/bkuser/biz/validators.py b/src/bk-user/bkuser/biz/validators.py index b91927f67..3a3e07947 100644 --- a/src/bk-user/bkuser/biz/validators.py +++ b/src/bk-user/bkuser/biz/validators.py @@ -52,5 +52,5 @@ def validate_logo(value): raise ValidationError(_("无效logo文件")) # Check if the size exceeds the specified limit - if len(decoded_data) / 1024 > settings.MAX_LOGO_SIZE: - raise ValidationError(_("logo 文件大小超过限制{}KB").format(settings.MAX_LOGO_SIZE)) + if len(decoded_data) > settings.MAX_LOGO_SIZE * 1024: + raise ValidationError(_("logo 文件大小,不可超过{}KB").format(settings.MAX_LOGO_SIZE)) From 2595850e8e09f1096d863848aeaa4cba15fc8c6f Mon Sep 17 00:00:00 2001 From: nero Date: Tue, 19 Dec 2023 16:36:41 +0800 Subject: [PATCH 3/6] =?UTF-8?q?refactor:=20cr=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/bk-user/bkuser/biz/validators.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bk-user/bkuser/biz/validators.py b/src/bk-user/bkuser/biz/validators.py index 3a3e07947..8bdfdd93d 100644 --- a/src/bk-user/bkuser/biz/validators.py +++ b/src/bk-user/bkuser/biz/validators.py @@ -53,4 +53,4 @@ def validate_logo(value): # Check if the size exceeds the specified limit if len(decoded_data) > settings.MAX_LOGO_SIZE * 1024: - raise ValidationError(_("logo 文件大小,不可超过{}KB").format(settings.MAX_LOGO_SIZE)) + raise ValidationError(_("Logo 文件大小不可超过 {} KB").format(settings.MAX_LOGO_SIZE)) From 432eb131091ee1a852d783fa38ba444435e1c43a Mon Sep 17 00:00:00 2001 From: nero Date: Wed, 20 Dec 2023 10:33:11 +0800 Subject: [PATCH 4/6] =?UTF-8?q?refactor:=20cr=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/bk-user/bkuser/biz/validators.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/bk-user/bkuser/biz/validators.py b/src/bk-user/bkuser/biz/validators.py index 8bdfdd93d..4351a4fe5 100644 --- a/src/bk-user/bkuser/biz/validators.py +++ b/src/bk-user/bkuser/biz/validators.py @@ -8,7 +8,6 @@ an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. """ -import base64 import logging import re @@ -44,13 +43,6 @@ def validate_logo(value): if not value: return - try: - decoded_data = base64.b64decode(value) - except Exception: - # Decoding failed or invalid Base64-encoded image - logger.exception("invalid image") - raise ValidationError(_("无效logo文件")) - - # Check if the size exceeds the specified limit - if len(decoded_data) > settings.MAX_LOGO_SIZE * 1024: + # base64_size = (实际数据大小)/3 *4 + if len(value) > (settings.MAX_LOGO_SIZE * 1024) // 3 * 4: raise ValidationError(_("Logo 文件大小不可超过 {} KB").format(settings.MAX_LOGO_SIZE)) From 6c0defc0d50cb6ec49adc00568829c038d1305dd Mon Sep 17 00:00:00 2001 From: nero Date: Wed, 20 Dec 2023 10:35:18 +0800 Subject: [PATCH 5/6] =?UTF-8?q?refactor:=20cr=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/bk-user/bkuser/biz/validators.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bk-user/bkuser/biz/validators.py b/src/bk-user/bkuser/biz/validators.py index 4351a4fe5..031785943 100644 --- a/src/bk-user/bkuser/biz/validators.py +++ b/src/bk-user/bkuser/biz/validators.py @@ -43,6 +43,6 @@ def validate_logo(value): if not value: return - # base64_size = (实际数据大小)/3 *4 + # logo是个base64字符串,base64数据实际大小 = (实际数据大小) //3 * 4,需要做大小转换 if len(value) > (settings.MAX_LOGO_SIZE * 1024) // 3 * 4: raise ValidationError(_("Logo 文件大小不可超过 {} KB").format(settings.MAX_LOGO_SIZE)) From 1955e3a0d90576476e8598d92b07da096980173e Mon Sep 17 00:00:00 2001 From: schnee Date: Thu, 21 Dec 2023 14:51:26 +0800 Subject: [PATCH 6/6] minor: update comments --- src/bk-user/bkuser/biz/validators.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bk-user/bkuser/biz/validators.py b/src/bk-user/bkuser/biz/validators.py index 031785943..2e2bb4288 100644 --- a/src/bk-user/bkuser/biz/validators.py +++ b/src/bk-user/bkuser/biz/validators.py @@ -43,6 +43,6 @@ def validate_logo(value): if not value: return - # logo是个base64字符串,base64数据实际大小 = (实际数据大小) //3 * 4,需要做大小转换 + # Logo 使用 Base64 编码,编码后长度 ≈ 原始图片字节长度 // 3 * 4 if len(value) > (settings.MAX_LOGO_SIZE * 1024) // 3 * 4: raise ValidationError(_("Logo 文件大小不可超过 {} KB").format(settings.MAX_LOGO_SIZE))