From 83dcdbe59d60db81b69f3d9c2a628330b651907a Mon Sep 17 00:00:00 2001 From: Wu Clan Date: Tue, 29 Jul 2025 22:51:31 +0800 Subject: [PATCH] Update the OAuth2 login password policy (#741) * Update the OAuth2 login password policy * Update the crud pwd * Update the reset pwd service --- backend/app/admin/crud/crud_user.py | 10 ++-- backend/app/admin/model/user.py | 4 +- backend/app/admin/service/user_service.py | 5 +- backend/plugin/oauth2/plugin.toml | 2 +- .../plugin/oauth2/service/oauth2_service.py | 53 ++++++++++--------- 5 files changed, 37 insertions(+), 37 deletions(-) diff --git a/backend/app/admin/crud/crud_user.py b/backend/app/admin/crud/crud_user.py index dc45b77c..152ded74 100644 --- a/backend/app/admin/crud/crud_user.py +++ b/backend/app/admin/crud/crud_user.py @@ -89,10 +89,8 @@ class CRUDUser(CRUDPlus[User]): :param obj: 注册用户参数 :return: """ - salt = bcrypt.gensalt() - obj.password = get_hash_password(obj.password, salt) dict_obj = obj.model_dump() - dict_obj.update({'is_staff': True, 'salt': salt}) + dict_obj.update({'is_staff': True, 'salt': None}) new_user = self.model(**dict_obj) stmt = select(Role) @@ -156,10 +154,12 @@ class CRUDUser(CRUDPlus[User]): :param db: 数据库会话 :param pk: 用户 ID - :param new_pwd: 新密码(已加密) + :param new_pwd: 新密码 :return: """ - return await self.update_model(db, pk, {'password': new_pwd}) + salt = bcrypt.gensalt() + new_pwd = get_hash_password(new_pwd, salt) + return await self.update_model(db, pk, {'password': new_pwd, 'salt': salt}) async def get_list(self, dept: int | None, username: str | None, phone: str | None, status: int | None) -> Select: """ diff --git a/backend/app/admin/model/user.py b/backend/app/admin/model/user.py index 7e03ade7..c387501e 100644 --- a/backend/app/admin/model/user.py +++ b/backend/app/admin/model/user.py @@ -27,8 +27,8 @@ class User(Base): uuid: Mapped[str] = mapped_column(String(50), init=False, default_factory=uuid4_str, unique=True) username: Mapped[str] = mapped_column(String(20), unique=True, index=True, comment='用户名') nickname: Mapped[str] = mapped_column(String(20), comment='昵称') - password: Mapped[str] = mapped_column(String(255), comment='密码') - salt: Mapped[bytes] = mapped_column(VARBINARY(255).with_variant(BYTEA(255), 'postgresql'), comment='加密盐') + password: Mapped[str | None] = mapped_column(String(255), comment='密码') + salt: Mapped[bytes | None] = mapped_column(VARBINARY(255).with_variant(BYTEA(255), 'postgresql'), comment='加密盐') email: Mapped[str | None] = mapped_column(String(50), default=None, unique=True, index=True, comment='邮箱') phone: Mapped[str | None] = mapped_column(String(11), default=None, comment='手机号') avatar: Mapped[str | None] = mapped_column(String(255), default=None, comment='头像') diff --git a/backend/app/admin/service/user_service.py b/backend/app/admin/service/user_service.py index d2ecfda9..acc8ed0a 100644 --- a/backend/app/admin/service/user_service.py +++ b/backend/app/admin/service/user_service.py @@ -18,7 +18,7 @@ from backend.app.admin.schema.user import ( ) from backend.common.enums import UserPermissionType from backend.common.exception import errors -from backend.common.security.jwt import get_hash_password, get_token, jwt_decode, password_verify, superuser_verify +from backend.common.security.jwt import get_token, jwt_decode, password_verify, superuser_verify from backend.core.conf import settings from backend.database.db import async_db_session from backend.database.redis import redis_client @@ -249,8 +249,7 @@ class UserService: raise errors.RequestError(msg='原密码错误') if obj.new_password != obj.confirm_password: raise errors.RequestError(msg='密码输入不一致') - new_pwd = get_hash_password(obj.new_password, user.salt) - count = await user_dao.reset_password(db, user.id, new_pwd) + count = await user_dao.reset_password(db, user.id, obj.new_password) key_prefix = [ f'{settings.TOKEN_REDIS_PREFIX}:{user.id}', f'{settings.TOKEN_REFRESH_REDIS_PREFIX}:{user.id}', diff --git a/backend/plugin/oauth2/plugin.toml b/backend/plugin/oauth2/plugin.toml index 0f3094d5..597a8ed3 100644 --- a/backend/plugin/oauth2/plugin.toml +++ b/backend/plugin/oauth2/plugin.toml @@ -1,6 +1,6 @@ [plugin] summary = 'OAuth 2.0' -version = '0.0.3' +version = '0.0.4' description = '通过 OAuth 2.0 的方式登录系统' author = 'wu-clan' diff --git a/backend/plugin/oauth2/service/oauth2_service.py b/backend/plugin/oauth2/service/oauth2_service.py index 7ccdd045..95bb4d30 100644 --- a/backend/plugin/oauth2/service/oauth2_service.py +++ b/backend/plugin/oauth2/service/oauth2_service.py @@ -57,35 +57,36 @@ class OAuth2Service: sid = user.get('id') nickname = user.get('name') - sys_user = None user_social = await user_social_dao.get_by_sid(db, str(sid), str(social.value)) - if not user_social: - if email: - sys_user = await user_dao.check_email(db, email) - - # 创建系统用户 - if not sys_user: - while await user_dao.get_by_username(db, username): - username = f'{username}_{text_captcha(5)}' - new_sys_user = AddOAuth2UserParam( - username=username, - password='123456', # 默认密码,可修改系统用户表进行默认密码检测并配合前端进行修改密码提示 - nickname=nickname, - email=email, - avatar=avatar, - ) - await user_dao.add_by_oauth2(db, new_sys_user) - await db.flush() - sys_user = await user_dao.get_by_username(db, username) - - # 绑定社交用户 - new_user_social = CreateUserSocialParam(sid=str(sid), source=social.value, user_id=sys_user.id) - await user_social_dao.create(db, new_user_social) - - if not sys_user: + if user_social: sys_user = await user_dao.get(db, user_social.user_id) - if avatar: + # 更新用户头像 + if not sys_user.avatar and avatar is not None: await user_dao.update_avatar(db, sys_user.id, avatar) + else: + sys_user = None + # 检测系统用户是否已存在 + if email: + sys_user = await user_dao.check_email(db, email) # 通过邮箱验证绑定保证邮箱真实性 + + # 创建系统用户 + if not sys_user: + while await user_dao.get_by_username(db, username): + username = f'{username}_{text_captcha(5)}' + new_sys_user = AddOAuth2UserParam( + username=username, + password=None, + nickname=nickname, + email=email, + avatar=avatar, + ) + await user_dao.add_by_oauth2(db, new_sys_user) + await db.flush() + sys_user = await user_dao.get_by_username(db, username) + + # 绑定社交账号 + new_user_social = CreateUserSocialParam(sid=str(sid), source=social.value, user_id=sys_user.id) + await user_social_dao.create(db, new_user_social) # 创建 token access_token = await jwt.create_access_token(