diff --git a/backend/apps/system/crud/user.py b/backend/apps/system/crud/user.py index 4c96d124..ae6ed887 100644 --- a/backend/apps/system/crud/user.py +++ b/backend/apps/system/crud/user.py @@ -3,7 +3,7 @@ from typing import Optional from sqlmodel import Session, func, select, delete as sqlmodel_delete from apps.system.models.system_model import UserWsModel, WorkspaceModel from apps.system.schemas.auth import CacheName, CacheNamespace -from apps.system.schemas.system_schema import BaseUserDTO, UserInfoDTO, UserWs +from apps.system.schemas.system_schema import EMAIL_REGEX, PWD_REGEX, BaseUserDTO, UserInfoDTO, UserWs from common.core.deps import SessionDep from common.core.sqlbot_cache import cache, clear_cache from common.utils.locale import I18n @@ -78,18 +78,7 @@ def check_email_exists(*, session: Session, email: str) -> bool: return session.exec(select(func.count()).select_from(UserModel).where(UserModel.email == email)).one() > 0 -# 预编译正则表达式,提高效率 -EMAIL_REGEX = re.compile( - r"^[a-zA-Z0-9]+([._-][a-zA-Z0-9]+)*@" - r"([a-zA-Z0-9]+(-[a-zA-Z0-9]+)*\.)+" - r"[a-zA-Z]{2,}$" -) -PWD_REGEX = re.compile( - r"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)" - r"(?=.*[~!@#$%^&*()_+\-={}|:\"<>?`\[\];',./])" - r"[A-Za-z\d~!@#$%^&*()_+\-={}|:\"<>?`\[\];',./]{8,20}$" -) def check_email_format(email: str) -> bool: return bool(EMAIL_REGEX.fullmatch(email)) diff --git a/backend/apps/system/schemas/system_schema.py b/backend/apps/system/schemas/system_schema.py index cb0c757f..ecec9ed2 100644 --- a/backend/apps/system/schemas/system_schema.py +++ b/backend/apps/system/schemas/system_schema.py @@ -1,8 +1,19 @@ from typing import Optional -from pydantic import BaseModel +from pydantic import BaseModel, Field, field_validator from common.core.schemas import BaseCreatorDTO +import re +EMAIL_REGEX = re.compile( + r"^[a-zA-Z0-9]+([._-][a-zA-Z0-9]+)*@" + r"([a-zA-Z0-9]+(-[a-zA-Z0-9]+)*\.)+" + r"[a-zA-Z]{2,}$" +) +PWD_REGEX = re.compile( + r"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)" + r"(?=.*[~!@#$%^&*()_+\-={}|:\"<>?`\[\];',./])" + r"[A-Za-z\d~!@#$%^&*()_+\-={}|:\"<>?`\[\];',./]{8,20}$" +) class model_status(BaseModel): status: bool ids: list[int] @@ -13,11 +24,11 @@ class UserLanguage(BaseModel): class BaseUser(BaseModel): - account: str + account: str = Field(min_length=1, max_length=100, description="用户账号") oid: int - + class BaseUserDTO(BaseUser, BaseCreatorDTO): - language: str + language: str = Field(pattern=r"^(zh-CN|en)$", default="zh-CN", description="用户语言") password: str status: int = 1 def to_dict(self): @@ -26,12 +37,23 @@ class BaseUserDTO(BaseUser, BaseCreatorDTO): "account": self.account, "oid": self.oid } + @field_validator("language") + def validate_language(cls, lang: str) -> str: + if not re.fullmatch(r"^(zh-CN|en)$", lang): + raise ValueError("Language must be 'zh-CN' or 'en'") + return lang class UserCreator(BaseUser): - name: str - email: str + name: str = Field(min_length=1, max_length=100, description="用户名") + email: str = Field(min_length=1, max_length=100, description="用户邮箱") status: int = 1 oid_list: Optional[list[int]] = None + + """ @field_validator("email") + def validate_email(cls, lang: str) -> str: + if not re.fullmatch(EMAIL_REGEX, lang): + raise ValueError("Email format is invalid!") + return lang """ class UserEditor(UserCreator, BaseCreatorDTO): pass