|
|
@ -1,14 +1,18 @@ |
|
|
|
from fastapi import Request |
|
|
|
from sqlalchemy.ext.asyncio import AsyncSession |
|
|
|
from typing import List |
|
|
|
from config.constant import CommonConstant |
|
|
|
from exceptions.exception import ServiceException |
|
|
|
from module_admin.dao.metaSecurity_dao import MetaSecurityDao |
|
|
|
from module_admin.entity.vo.common_vo import CrudResponseModel |
|
|
|
from module_admin.entity.vo.metasecurity_vo import MetaSecurityColModel, MetaSecurityRowModel,DeleteMetaSecurityModel |
|
|
|
from module_admin.entity.vo.metasecurity_vo import MetaSecurityColModel, MetaSecurityRowModel,DeleteMetaSecurityModel,MetaSecurityApiModel |
|
|
|
from utils.common_util import CamelCaseUtil |
|
|
|
import uuid |
|
|
|
|
|
|
|
from module_admin.dao.login_dao import login_by_account |
|
|
|
from module_admin.dao.user_dao import UserDao |
|
|
|
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine |
|
|
|
from sqlalchemy.orm import sessionmaker |
|
|
|
from sqlalchemy.exc import SQLAlchemyError |
|
|
|
from sqlalchemy import text |
|
|
|
import json |
|
|
|
|
|
|
|
class MetaSecurityService: |
|
|
|
""" |
|
|
@ -88,17 +92,19 @@ class MetaSecurityService: |
|
|
|
:return: 新增列配置校验结果 |
|
|
|
""" |
|
|
|
try: |
|
|
|
if isinstance(page_object.obj_value, str) and page_object.obj_value: |
|
|
|
if isinstance(page_object.obj_value, str) and page_object.obj_value: |
|
|
|
obj_values = page_object.obj_value.split(",") |
|
|
|
for value in obj_values: |
|
|
|
obj_names = page_object.obj_name.split(",") |
|
|
|
for value, name in zip(obj_values, obj_names): |
|
|
|
# 创建新的 page_object 实例,避免修改原始对象 |
|
|
|
new_page_object = MetaSecurityColModel(**page_object.model_dump(by_alias=True)) |
|
|
|
new_page_object.obj_value = value.strip() # 去除空格并赋值 |
|
|
|
new_page_object.obj_name = name.strip() # 去除空格并赋值 |
|
|
|
new_page_object.colId = str(uuid.uuid4()) |
|
|
|
# 调用 DAO 方法插入数据 |
|
|
|
await MetaSecurityDao.add_meta_security_col(query_db, new_page_object) |
|
|
|
await query_db.commit() |
|
|
|
return CrudResponseModel(is_success=True, message='新增列配置成功') |
|
|
|
await query_db.commit() |
|
|
|
return CrudResponseModel(is_success=True, message='新增列配置成功') |
|
|
|
except Exception as e: |
|
|
|
await query_db.rollback() |
|
|
|
raise e |
|
|
@ -116,10 +122,12 @@ class MetaSecurityService: |
|
|
|
try: |
|
|
|
if isinstance(page_object.obj_value, str) and page_object.obj_value: |
|
|
|
obj_values = page_object.obj_value.split(",") |
|
|
|
for value in obj_values: |
|
|
|
obj_names = page_object.obj_name.split(",") |
|
|
|
for value, name in zip(obj_values, obj_names): |
|
|
|
# 创建新的 page_object 实例,避免修改原始对象 |
|
|
|
new_page_object = MetaSecurityRowModel(**page_object.model_dump(by_alias=True)) |
|
|
|
new_page_object.obj_value = value.strip() # 去除空格并赋值 |
|
|
|
new_page_object.obj_name = name.strip() # 去除空格并赋值 |
|
|
|
new_page_object.rowId = str(uuid.uuid4()) |
|
|
|
# 调用 DAO 方法插入数据 |
|
|
|
await MetaSecurityDao.add_meta_security_row(query_db, new_page_object) |
|
|
@ -266,5 +274,100 @@ class MetaSecurityService: |
|
|
|
raise e |
|
|
|
else: |
|
|
|
raise ServiceException(message='传入行配置ID为空') |
|
|
|
|
|
|
|
|
|
|
|
@classmethod |
|
|
|
async def getMetaSercuitybysql(cls, request: Request, query_db: AsyncSession, page_object: MetaSecurityApiModel): |
|
|
|
#1.校验用户 |
|
|
|
if not page_object.username: |
|
|
|
raise ServiceException(data='', message='用户名不能为空!') |
|
|
|
user = await login_by_account(query_db, page_object.username) |
|
|
|
if not user: |
|
|
|
raise ServiceException(data='', message='用户不存在') |
|
|
|
if not page_object.password == user[0].password: |
|
|
|
raise ServiceException(data='', message='用户密码错误!') |
|
|
|
query_user = await UserDao.get_user_by_id(query_db, user_id=user[0].user_id) |
|
|
|
role_id_list = [item.role_id for item in query_user.get('user_role_info')] |
|
|
|
#2.查询用户及该用户角色下的所有行列配置 |
|
|
|
# 列配置 |
|
|
|
user_col_list=await MetaSecurityDao.get_api_col_list(query_db, page_object.dbRId,page_object.tableName, '0',user[0].user_id) |
|
|
|
role_col_list = [] |
|
|
|
for role_id in role_id_list: |
|
|
|
role_cols = await MetaSecurityDao.get_api_col_list( |
|
|
|
query_db, page_object.dbRId, page_object.tableName, '1', role_id |
|
|
|
) |
|
|
|
role_col_list.extend(role_cols) # 将每个角色的列配置合并到列表中 |
|
|
|
|
|
|
|
# 行配置 |
|
|
|
user_row_list=await MetaSecurityDao.get_api_row_list(query_db, page_object.dbRId,page_object.tableName, '0',user[0].user_id) |
|
|
|
role_row_list = [] |
|
|
|
for role_id in role_id_list: |
|
|
|
role_rows = await MetaSecurityDao.get_api_row_list( |
|
|
|
query_db, page_object.dbRId, page_object.tableName, '1', role_id |
|
|
|
) |
|
|
|
role_row_list.extend(role_rows) # 将每个角色的行配置合并到列表中 |
|
|
|
result = { |
|
|
|
"user_col_list": user_col_list, |
|
|
|
"role_col_list": role_col_list, |
|
|
|
"role_row_list": role_row_list, |
|
|
|
"user_row_list": user_row_list |
|
|
|
} |
|
|
|
# return result |
|
|
|
#3.根据行列配置控制原始sql |
|
|
|
#4.测试数据源连接是否正常 |
|
|
|
dataParams ={"user":"dbf","password":"1q2w3e4r","address":"jdbc:mysql://47.113.147.166:3306","database":"dash_test_w","jdbcUrl":"jdbc:mysql://47.113.147.166:3306/dash_test_w","driverClassName":"com.mysql.cj.jdbc.Driver","validationQuery":"select 1"} |
|
|
|
dbConnent = cls.get_db_engine('mysql',dataParams) |
|
|
|
query = "SELECT * FROM msq_table_constraints" |
|
|
|
result = await cls.execute_sql(dbConnent, query) |
|
|
|
return result |
|
|
|
#5.执行原始sql |
|
|
|
#6.执行控制后的sql |
|
|
|
#7.执行结果 |
|
|
|
|
|
|
|
def get_db_engine(db_type: str, db_params: dict): |
|
|
|
try: |
|
|
|
if db_type == "mysql": |
|
|
|
address = db_params['address'] |
|
|
|
if address.startswith("jdbc:mysql://"): |
|
|
|
# 去掉 jdbc:mysql:// 部分 |
|
|
|
address = address[len("jdbc:mysql://"):] |
|
|
|
db_params['address'] = address |
|
|
|
conn_str=f"mysql+aiomysql://{db_params['user']}:{db_params['password']}@{db_params['address']}/{db_params['database']}" |
|
|
|
print(f"数据库连接字符串: {conn_str}") # 输出调试信息 |
|
|
|
return create_async_engine(conn_str) |
|
|
|
elif db_type == "postgresql": |
|
|
|
return create_async_engine(f"postgresql+asyncpg://{db_params['user']}:{db_params['password']}@{db_params['address']}/{db_params['database']}") |
|
|
|
# 你可以根据需求添加更多数据库类型 |
|
|
|
else: |
|
|
|
raise ValueError("不支持的数据库类型") |
|
|
|
except SQLAlchemyError as e: |
|
|
|
# 捕获SQLAlchemy相关的数据库连接错误 |
|
|
|
raise ConnectionError(f"数据库连接失败: {e}") |
|
|
|
except Exception as e: |
|
|
|
# 捕获其他非预期的错误 |
|
|
|
raise RuntimeError(f"连接过程中发生了未知错误: {e}") |
|
|
|
@classmethod |
|
|
|
async def execute_sql(cls, dbConnent, sql_query: str,sql_type: str): |
|
|
|
# 创建异步会话 |
|
|
|
async with dbConnent.begin(): |
|
|
|
# 获取会话对象 |
|
|
|
async_session = sessionmaker( |
|
|
|
dbConnent, class_=AsyncSession, expire_on_commit=False |
|
|
|
) |
|
|
|
async with async_session() as session: |
|
|
|
try: |
|
|
|
# 执行原始SQL查询 |
|
|
|
query = text(sql_query) |
|
|
|
result = await session.execute(query) |
|
|
|
|
|
|
|
# 获取所有结果 |
|
|
|
rows = result.fetchall() |
|
|
|
|
|
|
|
# 获取列名 |
|
|
|
columns = result.keys() |
|
|
|
|
|
|
|
# 将每一行转化为字典,键为列名 |
|
|
|
result_dict = [dict(zip(columns, row)) for row in rows] |
|
|
|
|
|
|
|
# 转换为 JSON 字符串 |
|
|
|
return json.dumps(result_dict, ensure_ascii=False, indent=4) |
|
|
|
except SQLAlchemyError as e: |
|
|
|
raise RuntimeError(f"{sql_type}执行 SQL 查询时发生错误: {e}") |