From f8f7b0ec1aaac8d584a0db9d036fda3944846601 Mon Sep 17 00:00:00 2001 From: corevibe555 <45244658+corevibe555@users.noreply.github.com> Date: Wed, 8 Apr 2026 01:51:11 +0300 Subject: [PATCH] refactor(api): deduplicate shared auth request payloads into auth_entities.py (#34694) --- .../console/auth/forgot_password.py | 31 ++++------------- api/controllers/console/auth/login.py | 5 ++- api/controllers/web/forgot_password.py | 33 ++++--------------- api/controllers/web/login.py | 6 ++-- api/services/entities/auth_entities.py | 31 +++++++++++++++++ 5 files changed, 49 insertions(+), 57 deletions(-) create mode 100644 api/services/entities/auth_entities.py diff --git a/api/controllers/console/auth/forgot_password.py b/api/controllers/console/auth/forgot_password.py index 844f3c91ff..63bc98b53f 100644 --- a/api/controllers/console/auth/forgot_password.py +++ b/api/controllers/console/auth/forgot_password.py @@ -3,7 +3,7 @@ import secrets from flask import request from flask_restx import Resource -from pydantic import BaseModel, Field, field_validator +from pydantic import BaseModel, Field from sqlalchemy.orm import sessionmaker from controllers.common.schema import register_schema_models @@ -20,35 +20,18 @@ from controllers.console.wraps import email_password_login_enabled, setup_requir from events.tenant_event import tenant_was_created from extensions.ext_database import db from libs.helper import EmailStr, extract_remote_ip -from libs.password import hash_password, valid_password +from libs.password import hash_password from services.account_service import AccountService, TenantService +from services.entities.auth_entities import ( + ForgotPasswordCheckPayload, + ForgotPasswordResetPayload, + ForgotPasswordSendPayload, +) from services.feature_service import FeatureService DEFAULT_REF_TEMPLATE_SWAGGER_2_0 = "#/definitions/{model}" -class ForgotPasswordSendPayload(BaseModel): - email: EmailStr = Field(...) - language: str | None = Field(default=None) - - -class ForgotPasswordCheckPayload(BaseModel): - email: EmailStr = Field(...) - code: str = Field(...) - token: str = Field(...) - - -class ForgotPasswordResetPayload(BaseModel): - token: str = Field(...) - new_password: str = Field(...) - password_confirm: str = Field(...) - - @field_validator("new_password", "password_confirm") - @classmethod - def validate_password(cls, value: str) -> str: - return valid_password(value) - - class ForgotPasswordEmailResponse(BaseModel): result: str = Field(description="Operation result") data: str | None = Field(default=None, description="Reset token") diff --git a/api/controllers/console/auth/login.py b/api/controllers/console/auth/login.py index 1aaa5d3a62..962cc83b0e 100644 --- a/api/controllers/console/auth/login.py +++ b/api/controllers/console/auth/login.py @@ -42,6 +42,7 @@ from libs.token import ( ) from services.account_service import AccountService, InvitationDetailDict, RegisterService, TenantService from services.billing_service import BillingService +from services.entities.auth_entities import LoginPayloadBase from services.errors.account import AccountRegisterError from services.errors.workspace import WorkSpaceNotAllowedCreateError, WorkspacesLimitExceededError from services.feature_service import FeatureService @@ -49,9 +50,7 @@ from services.feature_service import FeatureService DEFAULT_REF_TEMPLATE_SWAGGER_2_0 = "#/definitions/{model}" -class LoginPayload(BaseModel): - email: EmailStr = Field(..., description="Email address") - password: str = Field(..., description="Password") +class LoginPayload(LoginPayloadBase): remember_me: bool = Field(default=False, description="Remember me flag") invite_token: str | None = Field(default=None, description="Invitation token") diff --git a/api/controllers/web/forgot_password.py b/api/controllers/web/forgot_password.py index d69571cc9c..80c3289fb4 100644 --- a/api/controllers/web/forgot_password.py +++ b/api/controllers/web/forgot_password.py @@ -3,7 +3,6 @@ import secrets from flask import request from flask_restx import Resource -from pydantic import BaseModel, Field, field_validator from sqlalchemy.orm import sessionmaker from controllers.common.schema import register_schema_models @@ -19,33 +18,15 @@ from controllers.console.error import EmailSendIpLimitError from controllers.console.wraps import email_password_login_enabled, only_edition_enterprise, setup_required from controllers.web import web_ns from extensions.ext_database import db -from libs.helper import EmailStr, extract_remote_ip -from libs.password import hash_password, valid_password +from libs.helper import extract_remote_ip +from libs.password import hash_password from models.account import Account from services.account_service import AccountService - - -class ForgotPasswordSendPayload(BaseModel): - email: EmailStr - language: str | None = None - - -class ForgotPasswordCheckPayload(BaseModel): - email: EmailStr - code: str - token: str = Field(min_length=1) - - -class ForgotPasswordResetPayload(BaseModel): - token: str = Field(min_length=1) - new_password: str - password_confirm: str - - @field_validator("new_password", "password_confirm") - @classmethod - def validate_password(cls, value: str) -> str: - return valid_password(value) - +from services.entities.auth_entities import ( + ForgotPasswordCheckPayload, + ForgotPasswordResetPayload, + ForgotPasswordSendPayload, +) register_schema_models(web_ns, ForgotPasswordSendPayload, ForgotPasswordCheckPayload, ForgotPasswordResetPayload) diff --git a/api/controllers/web/login.py b/api/controllers/web/login.py index a824f6d487..ae0e6789ef 100644 --- a/api/controllers/web/login.py +++ b/api/controllers/web/login.py @@ -29,13 +29,11 @@ from libs.token import ( ) from services.account_service import AccountService from services.app_service import AppService +from services.entities.auth_entities import LoginPayloadBase from services.webapp_auth_service import WebAppAuthService -class LoginPayload(BaseModel): - email: EmailStr - password: str - +class LoginPayload(LoginPayloadBase): @field_validator("password") @classmethod def validate_password(cls, value: str) -> str: diff --git a/api/services/entities/auth_entities.py b/api/services/entities/auth_entities.py new file mode 100644 index 0000000000..6b720a4607 --- /dev/null +++ b/api/services/entities/auth_entities.py @@ -0,0 +1,31 @@ +from pydantic import BaseModel, Field, field_validator + +from libs.helper import EmailStr +from libs.password import valid_password + + +class LoginPayloadBase(BaseModel): + email: EmailStr + password: str + + +class ForgotPasswordSendPayload(BaseModel): + email: EmailStr + language: str | None = None + + +class ForgotPasswordCheckPayload(BaseModel): + email: EmailStr + code: str + token: str = Field(min_length=1) + + +class ForgotPasswordResetPayload(BaseModel): + token: str = Field(min_length=1) + new_password: str + password_confirm: str + + @field_validator("new_password", "password_confirm") + @classmethod + def validate_password(cls, value: str) -> str: + return valid_password(value)