Compare commits

...

2 Commits

Author SHA1 Message Date
xueyinfei 694e33aae9 Merge remote-tracking branch 'origin/master' 3 months ago
xueyinfei fc98d8a34b 用户域同步逻辑 3 months ago
  1. 3
      vue-fastapi-backend/module_admin/controller/login_controller.py
  2. 27
      vue-fastapi-backend/module_admin/controller/user_controller.py
  3. 143
      vue-fastapi-backend/module_admin/service/user_service.py
  4. 10
      vue-fastapi-backend/utils/pwd_util.py
  5. 2
      vue-fastapi-frontend/src/views/system/user/profile/resetPwd.vue

3
vue-fastapi-backend/module_admin/controller/login_controller.py

@ -66,7 +66,8 @@ async def login(
ex=timedelta(minutes=JwtConfig.jwt_redis_expire_minutes), ex=timedelta(minutes=JwtConfig.jwt_redis_expire_minutes),
) )
await UserService.edit_user_services( 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('登录成功') logger.info('登录成功')
# 判断请求是否来自于api文档,如果是返回指定格式的结果,用于修复api文档认证成功后token显示undefined的bug # 判断请求是否来自于api文档,如果是返回指定格式的结果,用于修复api文档认证成功后token显示undefined的bug

27
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( await RoleService.check_role_data_scope_services(
query_db, ','.join([str(item) for item in add_user.role_ids]), role_data_scope_sql 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_by = current_user.user.user_name
add_user.create_time = datetime.now() add_user.create_time = datetime.now()
add_user.update_by = current_user.user.user_name add_user.update_by = current_user.user.user_name
add_user.update_time = datetime.now() 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) logger.info(add_user_result.message)
return ResponseUtil.success(msg=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_by = current_user.user.user_name
edit_user.update_time = datetime.now() 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) logger.info(edit_user_result.message)
return ResponseUtil.success(msg=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: if not current_user.user.admin:
await UserService.check_user_data_scope_services(query_db, int(user_id), data_scope_sql) 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 = 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) logger.info(delete_user_result.message)
return ResponseUtil.success(msg=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) await UserService.check_user_data_scope_services(query_db, reset_user.user_id, data_scope_sql)
edit_user = EditUserModel( edit_user = EditUserModel(
userId=reset_user.user_id, 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, updateBy=current_user.user.user_name,
updateTime=datetime.now(), updateTime=datetime.now(),
type='pwd', 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) logger.info(edit_user_result.message)
return ResponseUtil.success(msg=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(), updateTime=datetime.now(),
type='status', 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) logger.info(edit_user_result.message)
return ResponseUtil.success(msg=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(), updateTime=datetime.now(),
type='avatar', 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) logger.info(edit_user_result.message)
return ResponseUtil.success(dict_content={'imgUrl': edit_user.avatar}, msg=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 [], postIds=current_user.user.post_ids.split(',') if current_user.user.post_ids else [],
role=current_user.user.role, 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) logger.info(edit_user_result.message)
return ResponseUtil.success(msg=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, updateBy=current_user.user.user_name,
updateTime=datetime.now(), 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) logger.info(reset_user_result.message)
return ResponseUtil.success(msg=reset_user_result.message) return ResponseUtil.success(msg=reset_user_result.message)

143
vue-fastapi-backend/module_admin/service/user_service.py

@ -1,5 +1,6 @@
import io import io
import pandas as pd import pandas as pd
import requests
from datetime import datetime from datetime import datetime
from fastapi import Request, UploadFile from fastapi import Request, UploadFile
from sqlalchemy.ext.asyncio import AsyncSession 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.common_util import CamelCaseUtil, export_list2excel, get_excel_template
from utils.page_util import PageResponseModel from utils.page_util import PageResponseModel
from utils.pwd_util import PwdUtil from utils.pwd_util import PwdUtil
from config.env import AppConfig
class UserService: class UserService:
@ -144,14 +146,19 @@ class UserService:
return CommonConstant.UNIQUE return CommonConstant.UNIQUE
@classmethod @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 新增用户信息service
:param currentPassword: 当前用户密码
:param currentUserName: 当前用户名
:param query_db: orm对象 :param query_db: orm对象
:param page_object: 新增用户对象 :param page_object: 新增用户对象
:return: 新增用户校验结果 :return: 新增用户校验结果
""" """
dsPassword = page_object.password
page_object.password = PwdUtil.md5_hash(page_object.password)
add_user = UserModel(**page_object.model_dump(by_alias=True)) add_user = UserModel(**page_object.model_dump(by_alias=True))
if not await cls.check_user_name_unique_services(query_db, page_object): if not await cls.check_user_name_unique_services(query_db, page_object):
raise ServiceException(message=f'新增用户{page_object.user_name}失败,登录账号已存在') raise ServiceException(message=f'新增用户{page_object.user_name}失败,登录账号已存在')
@ -161,6 +168,23 @@ class UserService:
raise ServiceException(message=f'新增用户{page_object.user_name}失败,邮箱账号已存在') raise ServiceException(message=f'新增用户{page_object.user_name}失败,邮箱账号已存在')
else: else:
try: 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) add_result = await UserDao.add_user_dao(query_db, add_user)
user_id = add_result.user_id user_id = add_result.user_id
if page_object.role_ids: if page_object.role_ids:
@ -176,10 +200,13 @@ class UserService:
raise e raise e
@classmethod @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 编辑用户信息service
:param currentPassword: 当前用户密码
:param currentUserName: 当前用户名称
:param query_db: orm对象 :param query_db: orm对象
:param page_object: 编辑用户对象 :param page_object: 编辑用户对象
:return: 编辑用户校验结果 :return: 编辑用户校验结果
@ -201,6 +228,24 @@ class UserService:
elif page_object.email and not await cls.check_email_unique_services(query_db, page_object): elif page_object.email and not await cls.check_email_unique_services(query_db, page_object):
raise ServiceException(message=f'修改用户{page_object.user_name}失败,邮箱账号已存在') raise ServiceException(message=f'修改用户{page_object.user_name}失败,邮箱账号已存在')
try: 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) await UserDao.edit_user_dao(query_db, edit_user)
if page_object.type != 'status' and page_object.type != 'avatar' and page_object.type != 'pwd': 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)) await UserDao.delete_user_role_dao(query_db, UserRoleModel(userId=page_object.user_id))
@ -224,10 +269,13 @@ class UserService:
raise ServiceException(message='用户不存在') raise ServiceException(message='用户不存在')
@classmethod @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 删除用户信息service
:param currentPassword: 当前用户密码
:param currentUserName: 当前用户名称
:param query_db: orm对象 :param query_db: orm对象
:param page_object: 删除用户对象 :param page_object: 删除用户对象
:return: 删除用户校验结果 :return: 删除用户校验结果
@ -236,9 +284,23 @@ class UserService:
user_id_list = page_object.user_ids.split(',') user_id_list = page_object.user_ids.split(',')
try: try:
for user_id in user_id_list: for user_id in user_id_list:
user_info = await cls.user_detail_services(query_db, user_id)
user_id_dict = dict( user_id_dict = dict(
userId=user_id, updateBy=page_object.update_by, updateTime=page_object.update_time 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_role_dao(query_db, UserRoleModel(**user_id_dict))
await UserDao.delete_user_post_dao(query_db, UserPostModel(**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)) await UserDao.delete_user_dao(query_db, UserModel(**user_id_dict))
@ -312,18 +374,23 @@ class UserService:
) )
@classmethod @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 重置用户密码service
:param currentPassword: 当前用户密码
:param currentUserName: 当前用户名
:param query_db: orm对象 :param query_db: orm对象
:param page_object: 重置用户对象 :param page_object: 重置用户对象
:return: 重置用户校验结果 :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'}) 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: 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 PwdUtil.md5_hash(page_object.old_password) == user.password:
if not page_object.old_password == user.password:
raise ServiceException(message='修改密码失败,旧密码错误') raise ServiceException(message='修改密码失败,旧密码错误')
elif page_object.password == user.password: elif page_object.password == user.password:
raise ServiceException(message='新密码不能与旧密码相同') raise ServiceException(message='新密码不能与旧密码相同')
@ -333,8 +400,24 @@ class UserService:
del reset_user['sms_code'] del reset_user['sms_code']
del reset_user['session_id'] del reset_user['session_id']
try: try:
# reset_user['password'] = PwdUtil.get_password_hash(page_object.password) payload = {
reset_user['password'] = page_object.password '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 UserDao.edit_user_dao(query_db, reset_user)
await query_db.commit() await query_db.commit()
return CrudResponseModel(is_success=True, message='重置成功') return CrudResponseModel(is_success=True, message='重置成功')
@ -380,6 +463,9 @@ class UserService:
df.rename(columns=header_dict, inplace=True) df.rename(columns=header_dict, inplace=True)
add_error_result = [] add_error_result = []
count = 0 count = 0
pwd = await ConfigService.query_config_list_from_cache_services(
request.app.state.redis, 'sys.user.initPassword'
)
try: try:
for index, row in df.iterrows(): for index, row in df.iterrows():
count = count + 1 count = count + 1
@ -396,11 +482,7 @@ class UserService:
add_user = UserModel( add_user = UserModel(
deptId=row['dept_id'], deptId=row['dept_id'],
userName=row['user_name'], userName=row['user_name'],
password=PwdUtil.get_password_hash( password=PwdUtil.md5_hash(pwd),
await ConfigService.query_config_list_from_cache_services(
request.app.state.redis, 'sys.user.initPassword'
)
),
nickName=row['nick_name'], nickName=row['nick_name'],
email=row['email'], email=row['email'],
phonenumber=str(row['phonenumber']), phonenumber=str(row['phonenumber']),
@ -436,6 +518,24 @@ class UserService:
query_db, edit_user_model.dept_id, dept_data_scope_sql query_db, edit_user_model.dept_id, dept_data_scope_sql
) )
edit_user = edit_user_model.model_dump(exclude_unset=True) 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) await UserDao.edit_user_dao(query_db, edit_user)
else: else:
add_error_result.append(f"{count}.用户账号{row['user_name']}已存在") add_error_result.append(f"{count}.用户账号{row['user_name']}已存在")
@ -445,6 +545,23 @@ class UserService:
await DeptService.check_dept_data_scope_services( await DeptService.check_dept_data_scope_services(
query_db, add_user.dept_id, dept_data_scope_sql 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 UserDao.add_user_dao(query_db, add_user)
await query_db.commit() await query_db.commit()
return CrudResponseModel(is_success=True, message='\n'.join(add_error_result)) return CrudResponseModel(is_success=True, message='\n'.join(add_error_result))

10
vue-fastapi-backend/utils/pwd_util.py

@ -1,9 +1,19 @@
from passlib.context import CryptContext from passlib.context import CryptContext
import hashlib
pwd_context = CryptContext(schemes=['bcrypt'], deprecated='auto') pwd_context = CryptContext(schemes=['bcrypt'], deprecated='auto')
class PwdUtil: 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
""" """
密码工具类 密码工具类
""" """

2
vue-fastapi-frontend/src/views/system/user/profile/resetPwd.vue

@ -45,7 +45,7 @@ const rules = ref({
function submit() { function submit() {
proxy.$refs.pwdRef.validate(valid => { proxy.$refs.pwdRef.validate(valid => {
if (valid) { if (valid) {
updateUserPwd(md5(user.oldPassword), md5(user.newPassword)).then(response => { updateUserPwd(user.oldPassword, user.newPassword).then(response => {
proxy.$modal.msgSuccess("修改成功"); proxy.$modal.msgSuccess("修改成功");
}); });
} }

Loading…
Cancel
Save