From fc98d8a34b4c91e6d103e2ecaedf82048d0443ca Mon Sep 17 00:00:00 2001 From: xueyinfei <1207092115@qq.com> Date: Wed, 26 Feb 2025 10:05:42 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=A8=E6=88=B7=E5=9F=9F=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/login_controller.py | 3 +- .../controller/user_controller.py | 27 ++-- .../module_admin/service/user_service.py | 143 ++++++++++++++++-- vue-fastapi-backend/utils/pwd_util.py | 10 ++ .../views/system/user/profile/resetPwd.vue | 2 +- 5 files changed, 160 insertions(+), 25 deletions(-) diff --git a/vue-fastapi-backend/module_admin/controller/login_controller.py b/vue-fastapi-backend/module_admin/controller/login_controller.py index 6d13fcc..45c5a6d 100644 --- a/vue-fastapi-backend/module_admin/controller/login_controller.py +++ b/vue-fastapi-backend/module_admin/controller/login_controller.py @@ -66,7 +66,8 @@ async def login( ex=timedelta(minutes=JwtConfig.jwt_redis_expire_minutes), ) await UserService.edit_user_services( - query_db, EditUserModel(userId=result[0].user_id, loginDate=datetime.now(), type='status') + query_db, EditUserModel(userId=result[0].user_id, loginDate=datetime.now(), type='status'), + user.user_name, user.password ) logger.info('登录成功') # 判断请求是否来自于api文档,如果是返回指定格式的结果,用于修复api文档认证成功后token显示undefined的bug diff --git a/vue-fastapi-backend/module_admin/controller/user_controller.py b/vue-fastapi-backend/module_admin/controller/user_controller.py index 4af1850..567684c 100644 --- a/vue-fastapi-backend/module_admin/controller/user_controller.py +++ b/vue-fastapi-backend/module_admin/controller/user_controller.py @@ -86,12 +86,12 @@ async def add_system_user( await RoleService.check_role_data_scope_services( query_db, ','.join([str(item) for item in add_user.role_ids]), role_data_scope_sql ) - add_user.password = PwdUtil.get_password_hash(add_user.password) + # add_user.password = PwdUtil.get_password_hash(add_user.password) add_user.create_by = current_user.user.user_name add_user.create_time = datetime.now() add_user.update_by = current_user.user.user_name add_user.update_time = datetime.now() - add_user_result = await UserService.add_user_services(query_db, add_user) + add_user_result = await UserService.add_user_services(query_db, add_user, current_user.user.user_name, current_user.user.password) logger.info(add_user_result.message) return ResponseUtil.success(msg=add_user_result.message) @@ -118,7 +118,8 @@ async def edit_system_user( ) edit_user.update_by = current_user.user.user_name edit_user.update_time = datetime.now() - edit_user_result = await UserService.edit_user_services(query_db, edit_user) + edit_user_result = await UserService.edit_user_services(query_db, edit_user, + current_user.user.user_name, current_user.user.password) logger.info(edit_user_result.message) return ResponseUtil.success(msg=edit_user_result.message) @@ -144,7 +145,8 @@ async def delete_system_user( if not current_user.user.admin: await UserService.check_user_data_scope_services(query_db, int(user_id), data_scope_sql) delete_user = DeleteUserModel(userIds=user_ids, updateBy=current_user.user.user_name, updateTime=datetime.now()) - delete_user_result = await UserService.delete_user_services(query_db, delete_user) + delete_user_result = await UserService.delete_user_services(query_db, delete_user, + current_user.user.user_name, current_user.user.password) logger.info(delete_user_result.message) return ResponseUtil.success(msg=delete_user_result.message) @@ -164,12 +166,13 @@ async def reset_system_user_pwd( await UserService.check_user_data_scope_services(query_db, reset_user.user_id, data_scope_sql) edit_user = EditUserModel( userId=reset_user.user_id, - password=PwdUtil.get_password_hash(reset_user.password), + password=PwdUtil.md5_hash(reset_user.password), updateBy=current_user.user.user_name, updateTime=datetime.now(), type='pwd', ) - edit_user_result = await UserService.edit_user_services(query_db, edit_user) + edit_user_result = await UserService.edit_user_services(query_db, edit_user, + current_user.user.user_name, current_user.user.password) logger.info(edit_user_result.message) return ResponseUtil.success(msg=edit_user_result.message) @@ -194,7 +197,8 @@ async def change_system_user_status( updateTime=datetime.now(), type='status', ) - edit_user_result = await UserService.edit_user_services(query_db, edit_user) + edit_user_result = await UserService.edit_user_services(query_db, edit_user, + current_user.user.user_name, current_user.user.password) logger.info(edit_user_result.message) return ResponseUtil.success(msg=edit_user_result.message) @@ -261,7 +265,8 @@ async def change_system_user_profile_avatar( updateTime=datetime.now(), type='avatar', ) - edit_user_result = await UserService.edit_user_services(query_db, edit_user) + edit_user_result = await UserService.edit_user_services(query_db, edit_user, + current_user.user.user_name, current_user.user.password) logger.info(edit_user_result.message) return ResponseUtil.success(dict_content={'imgUrl': edit_user.avatar}, msg=edit_user_result.message) @@ -286,7 +291,8 @@ async def change_system_user_profile_info( postIds=current_user.user.post_ids.split(',') if current_user.user.post_ids else [], role=current_user.user.role, ) - edit_user_result = await UserService.edit_user_services(query_db, edit_user) + edit_user_result = await UserService.edit_user_services(query_db, edit_user, + current_user.user.user_name, current_user.user.password) logger.info(edit_user_result.message) return ResponseUtil.success(msg=edit_user_result.message) @@ -307,7 +313,8 @@ async def reset_system_user_password( updateBy=current_user.user.user_name, updateTime=datetime.now(), ) - reset_user_result = await UserService.reset_user_services(query_db, reset_user) + reset_user_result = await UserService.reset_user_services(query_db, reset_user, current_user.user.user_name, + current_user.user.password) logger.info(reset_user_result.message) return ResponseUtil.success(msg=reset_user_result.message) diff --git a/vue-fastapi-backend/module_admin/service/user_service.py b/vue-fastapi-backend/module_admin/service/user_service.py index 492b1d9..415fc58 100644 --- a/vue-fastapi-backend/module_admin/service/user_service.py +++ b/vue-fastapi-backend/module_admin/service/user_service.py @@ -1,5 +1,6 @@ import io import pandas as pd +import requests from datetime import datetime from fastapi import Request, UploadFile from sqlalchemy.ext.asyncio import AsyncSession @@ -34,6 +35,7 @@ from module_admin.service.role_service import RoleService from utils.common_util import CamelCaseUtil, export_list2excel, get_excel_template from utils.page_util import PageResponseModel from utils.pwd_util import PwdUtil +from config.env import AppConfig class UserService: @@ -144,14 +146,19 @@ class UserService: return CommonConstant.UNIQUE @classmethod - async def add_user_services(cls, query_db: AsyncSession, page_object: AddUserModel): + async def add_user_services(cls, query_db: AsyncSession, page_object: AddUserModel, + currentUserName: str, currentPassword: str): """ 新增用户信息service + :param currentPassword: 当前用户密码 + :param currentUserName: 当前用户名 :param query_db: orm对象 :param page_object: 新增用户对象 :return: 新增用户校验结果 """ + dsPassword = page_object.password + page_object.password = PwdUtil.md5_hash(page_object.password) add_user = UserModel(**page_object.model_dump(by_alias=True)) if not await cls.check_user_name_unique_services(query_db, page_object): raise ServiceException(message=f'新增用户{page_object.user_name}失败,登录账号已存在') @@ -161,6 +168,23 @@ class UserService: raise ServiceException(message=f'新增用户{page_object.user_name}失败,邮箱账号已存在') else: try: + payload = {'userName': page_object.user_name, + 'userPassword': dsPassword, + 'tenantId': 1, + 'queue': '', + 'email': page_object.email, + 'phone': page_object.phonenumber, + 'state': 1 if page_object.status == '0' else 0 + } + headers = {'dashUserName': currentUserName, 'dashPassword': currentPassword} + response_post = requests.post(url=AppConfig.ds_server_url+'/dolphinscheduler/users/create', + params=payload, + headers=headers, verify=False) + if response_post.status_code != 200: + if response_post.status_code != 201: + raise Exception("服务异常,请确保各节点是否在线") + if not response_post.json().get('success'): + raise Exception(response_post.json().get('msg')) add_result = await UserDao.add_user_dao(query_db, add_user) user_id = add_result.user_id if page_object.role_ids: @@ -176,10 +200,13 @@ class UserService: raise e @classmethod - async def edit_user_services(cls, query_db: AsyncSession, page_object: EditUserModel): + async def edit_user_services(cls, query_db: AsyncSession, page_object: EditUserModel, + currentUserName: str, currentPassword: str): """ 编辑用户信息service + :param currentPassword: 当前用户密码 + :param currentUserName: 当前用户名称 :param query_db: orm对象 :param page_object: 编辑用户对象 :return: 编辑用户校验结果 @@ -201,6 +228,24 @@ class UserService: elif page_object.email and not await cls.check_email_unique_services(query_db, page_object): raise ServiceException(message=f'修改用户{page_object.user_name}失败,邮箱账号已存在') try: + payload = { + 'id': -1, + 'userName': user_info.data.user_name, + 'userPassword': page_object.password if page_object.password else '', + 'email': page_object.email if page_object.email else '', + 'phone': page_object.phonenumber if page_object.phonenumber else '', + 'tenantId': -1, + 'state': 1 if (page_object.status is None or page_object.status == '0') else 0 + } + headers = {'dashUserName': currentUserName, 'dashPassword': currentPassword} + response_post = requests.post(url=AppConfig.ds_server_url+'/dolphinscheduler/users/update', + params=payload, + headers=headers, verify=False) + if response_post.status_code != 200: + if response_post.status_code != 201: + raise Exception("服务异常,请确保各节点是否在线") + if not response_post.json().get('success'): + raise Exception(response_post.json().get('msg')) await UserDao.edit_user_dao(query_db, edit_user) if page_object.type != 'status' and page_object.type != 'avatar' and page_object.type != 'pwd': await UserDao.delete_user_role_dao(query_db, UserRoleModel(userId=page_object.user_id)) @@ -224,10 +269,13 @@ class UserService: raise ServiceException(message='用户不存在') @classmethod - async def delete_user_services(cls, query_db: AsyncSession, page_object: DeleteUserModel): + async def delete_user_services(cls, query_db: AsyncSession, page_object: DeleteUserModel, + currentUserName: str, currentPassword: str): """ 删除用户信息service + :param currentPassword: 当前用户密码 + :param currentUserName: 当前用户名称 :param query_db: orm对象 :param page_object: 删除用户对象 :return: 删除用户校验结果 @@ -236,9 +284,23 @@ class UserService: user_id_list = page_object.user_ids.split(',') try: for user_id in user_id_list: + user_info = await cls.user_detail_services(query_db, user_id) user_id_dict = dict( userId=user_id, updateBy=page_object.update_by, updateTime=page_object.update_time ) + payload = { + 'id': -1, + 'userName': user_info.user.user_name + } + headers = {'dashUserName': currentUserName, 'dashPassword': currentPassword} + response_post = requests.post(url=AppConfig.ds_server_url+'/dolphinscheduler/users/delete', + params=payload, + headers=headers, verify=False) + if response_post.status_code != 200: + if response_post.status_code != 201: + raise Exception("服务异常,请确保各节点是否在线") + if not response_post.json().get('success'): + raise Exception(response_post.json().get('msg')) await UserDao.delete_user_role_dao(query_db, UserRoleModel(**user_id_dict)) await UserDao.delete_user_post_dao(query_db, UserPostModel(**user_id_dict)) await UserDao.delete_user_dao(query_db, UserModel(**user_id_dict)) @@ -312,18 +374,23 @@ class UserService: ) @classmethod - async def reset_user_services(cls, query_db: AsyncSession, page_object: ResetUserModel): + async def reset_user_services(cls, query_db: AsyncSession, page_object: ResetUserModel, + currentUserName: str, currentPassword: str): """ 重置用户密码service + :param currentPassword: 当前用户密码 + :param currentUserName: 当前用户名 :param query_db: orm对象 :param page_object: 重置用户对象 :return: 重置用户校验结果 """ + dsPassword = page_object.password + page_object.password = PwdUtil.md5_hash(page_object.password) reset_user = page_object.model_dump(exclude_unset=True, exclude={'admin'}) + user = (await UserDao.get_user_detail_by_id(query_db, user_id=page_object.user_id)).get('user_basic_info') if page_object.old_password: - user = (await UserDao.get_user_detail_by_id(query_db, user_id=page_object.user_id)).get('user_basic_info') - if not page_object.old_password == user.password: + if not PwdUtil.md5_hash(page_object.old_password) == user.password: raise ServiceException(message='修改密码失败,旧密码错误') elif page_object.password == user.password: raise ServiceException(message='新密码不能与旧密码相同') @@ -333,8 +400,24 @@ class UserService: del reset_user['sms_code'] del reset_user['session_id'] try: - # reset_user['password'] = PwdUtil.get_password_hash(page_object.password) - reset_user['password'] = page_object.password + payload = { + 'id': -1, + 'userName': user.user_name, + 'userPassword': dsPassword, + 'email': user.email, + 'phone': user.phonenumber, + 'tenantId': -1, + 'state': 1 if user.status == '0' else 0 + } + headers = {'dashUserName': currentUserName, 'dashPassword': currentPassword} + response_post = requests.post(url=AppConfig.ds_server_url+'/dolphinscheduler/users/update', + params=payload, + headers=headers, verify=False) + if response_post.status_code != 200: + if response_post.status_code != 201: + raise Exception("服务异常,请确保各节点是否在线") + if not response_post.json().get('success'): + raise Exception(response_post.json().get('msg')) await UserDao.edit_user_dao(query_db, reset_user) await query_db.commit() return CrudResponseModel(is_success=True, message='重置成功') @@ -380,6 +463,9 @@ class UserService: df.rename(columns=header_dict, inplace=True) add_error_result = [] count = 0 + pwd = await ConfigService.query_config_list_from_cache_services( + request.app.state.redis, 'sys.user.initPassword' + ) try: for index, row in df.iterrows(): count = count + 1 @@ -396,11 +482,7 @@ class UserService: add_user = UserModel( deptId=row['dept_id'], userName=row['user_name'], - password=PwdUtil.get_password_hash( - await ConfigService.query_config_list_from_cache_services( - request.app.state.redis, 'sys.user.initPassword' - ) - ), + password=PwdUtil.md5_hash(pwd), nickName=row['nick_name'], email=row['email'], phonenumber=str(row['phonenumber']), @@ -436,6 +518,24 @@ class UserService: query_db, edit_user_model.dept_id, dept_data_scope_sql ) edit_user = edit_user_model.model_dump(exclude_unset=True) + payload = { + 'id': -1, + 'userName': user_info.user.user_name, + 'userPassword': '', + 'email': edit_user.email if edit_user.email else '', + 'phone': edit_user.phonenumber if edit_user.phonenumber else '', + 'tenantId': -1, + 'state': 1 if edit_user.status == '0' else 0 + } + headers = {'dashUserName': current_user.user.user_name, 'dashPassword': current_user.user.password} + response_post = requests.post(url=AppConfig.ds_server_url+'/dolphinscheduler/users/update', + params=payload, + headers=headers, verify=False) + if response_post.status_code != 200: + if response_post.status_code != 201: + raise Exception("服务异常,请确保各节点是否在线") + if not response_post.json().get('success'): + raise Exception(response_post.json().get('msg')) await UserDao.edit_user_dao(query_db, edit_user) else: add_error_result.append(f"{count}.用户账号{row['user_name']}已存在") @@ -445,6 +545,23 @@ class UserService: await DeptService.check_dept_data_scope_services( query_db, add_user.dept_id, dept_data_scope_sql ) + payload = {'userName': add_user.user_name, + 'userPassword': pwd, + 'tenantId': 1, + 'queue': '', + 'email': add_user.email, + 'phone': add_user.phonenumber, + 'state': 1 if add_user.status == '0' else 0 + } + headers = {'dashUserName': current_user.user.user_name, 'dashPassword': current_user.user.password} + response_post = requests.post(url=AppConfig.ds_server_url+'/dolphinscheduler/users/create', + params=payload, + headers=headers, verify=False) + if response_post.status_code != 200: + if response_post.status_code != 201: + raise Exception("服务异常,请确保各节点是否在线") + if not response_post.json().get('success'): + raise Exception(response_post.json().get('msg')) await UserDao.add_user_dao(query_db, add_user) await query_db.commit() return CrudResponseModel(is_success=True, message='\n'.join(add_error_result)) diff --git a/vue-fastapi-backend/utils/pwd_util.py b/vue-fastapi-backend/utils/pwd_util.py index 86e9c27..f255ec5 100644 --- a/vue-fastapi-backend/utils/pwd_util.py +++ b/vue-fastapi-backend/utils/pwd_util.py @@ -1,9 +1,19 @@ from passlib.context import CryptContext +import hashlib + pwd_context = CryptContext(schemes=['bcrypt'], deprecated='auto') class PwdUtil: + @classmethod + def md5_hash(cls, password): + # 创建一个md5 hash对象 + hash_object = hashlib.md5(password.encode()) + # 获取16进制的hash值 + hex_dig = hash_object.hexdigest() + return hex_dig + """ 密码工具类 """ diff --git a/vue-fastapi-frontend/src/views/system/user/profile/resetPwd.vue b/vue-fastapi-frontend/src/views/system/user/profile/resetPwd.vue index 4b08930..e9c53fd 100644 --- a/vue-fastapi-frontend/src/views/system/user/profile/resetPwd.vue +++ b/vue-fastapi-frontend/src/views/system/user/profile/resetPwd.vue @@ -45,7 +45,7 @@ const rules = ref({ function submit() { proxy.$refs.pwdRef.validate(valid => { if (valid) { - updateUserPwd(md5(user.oldPassword), md5(user.newPassword)).then(response => { + updateUserPwd(user.oldPassword, user.newPassword).then(response => { proxy.$modal.msgSuccess("修改成功"); }); }