44
55from fastapi import Request
66from sqlalchemy import ColumnElement , and_ , or_
7+ from sqlalchemy .ext .asyncio import AsyncSession
78
9+ from backend .app .admin .crud .crud_data_scope import data_scope_dao
810from backend .common .enums import RoleDataRuleExpressionType , RoleDataRuleOperatorType
911from backend .common .exception import errors
1012from backend .common .exception .errors import ServerError
1113from backend .core .conf import settings
1214from backend .utils .import_parse import dynamic_import_data_model
1315
1416if TYPE_CHECKING :
15- from backend .app .admin .schema .data_rule import GetDataRuleDetail
17+ from backend .app .admin .model import DataRule
18+
19+ pass
1620
1721
1822class RequestPermission :
@@ -47,33 +51,38 @@ async def __call__(self, request: Request) -> None:
4751 request .state .permission = self .value
4852
4953
50- def filter_data_permission (request : Request ) -> ColumnElement [bool ]:
54+ async def filter_data_permission (db : AsyncSession , request : Request ) -> ColumnElement [bool ]:
5155 """
5256 过滤数据权限,控制用户可见数据范围
5357
5458 使用场景:
55- - 用户登录前台后,控制其能看到哪些数据
56- - 根据用户角色和规则过滤数据访问权限
59+ - 控制用户能看到哪些数据
5760
61+ :param db: 数据库会话
5862 :param request: FastAPI 请求对象
5963 :return:
6064 """
61- # 获取用户角色和规则
62- data_rules = []
65+ # 获取用户角色和数据范围
66+ data_scopes = []
6367 for role in request .user .roles :
64- data_rules .extend (role .rules )
65- user_data_rules : list [GetDataRuleDetail ] = list (dict .fromkeys (data_rules ))
68+ data_scopes .extend (role .scopes )
6669
6770 # 超级管理员和无规则用户不做过滤
68- if request .user .is_superuser or not user_data_rules :
71+ if request .user .is_superuser or not data_scopes :
6972 return or_ (1 == 1 )
7073
74+ # 获取数据范围规则
75+ data_rule_list : list [DataRule ] = []
76+ for data_scope in data_scopes :
77+ data_scope_with_relation = await data_scope_dao .get_with_relation (db , data_scope .id )
78+ data_rule_list .extend (data_scope_with_relation .rules )
79+
7180 where_and_list = []
7281 where_or_list = []
7382
74- for rule in user_data_rules :
83+ for data_rule in list ( dict . fromkeys ( data_rule_list )) :
7584 # 验证规则模型
76- rule_model = rule .model
85+ rule_model = data_rule .model
7786 if rule_model not in settings .DATA_PERMISSION_MODELS :
7887 raise errors .NotFoundError (msg = '数据规则模型不存在' )
7988 model_ins = dynamic_import_data_model (settings .DATA_PERMISSION_MODELS [rule_model ])
@@ -82,38 +91,38 @@ def filter_data_permission(request: Request) -> ColumnElement[bool]:
8291 model_columns = [
8392 key for key in model_ins .__table__ .columns .keys () if key not in settings .DATA_PERMISSION_COLUMN_EXCLUDE
8493 ]
85- column = rule .column
94+ column = data_rule .column
8695 if column not in model_columns :
8796 raise errors .NotFoundError (msg = '数据规则模型列不存在' )
8897
8998 # 构建过滤条件
9099 column_obj = getattr (model_ins , column )
91- rule_expression = rule .expression
100+ rule_expression = data_rule .expression
92101 condition = None
93102 if rule_expression == RoleDataRuleExpressionType .eq :
94- condition = column_obj == rule .value
103+ condition = column_obj == data_rule .value
95104 elif rule_expression == RoleDataRuleExpressionType .ne :
96- condition = column_obj != rule .value
105+ condition = column_obj != data_rule .value
97106 elif rule_expression == RoleDataRuleExpressionType .gt :
98- condition = column_obj > rule .value
107+ condition = column_obj > data_rule .value
99108 elif rule_expression == RoleDataRuleExpressionType .ge :
100- condition = column_obj >= rule .value
109+ condition = column_obj >= data_rule .value
101110 elif rule_expression == RoleDataRuleExpressionType .lt :
102- condition = column_obj < rule .value
111+ condition = column_obj < data_rule .value
103112 elif rule_expression == RoleDataRuleExpressionType .le :
104- condition = column_obj <= rule .value
113+ condition = column_obj <= data_rule .value
105114 elif rule_expression == RoleDataRuleExpressionType .in_ :
106- values = rule .value .split (',' ) if isinstance (rule .value , str ) else rule .value
115+ values = data_rule .value .split (',' ) if isinstance (data_rule .value , str ) else data_rule .value
107116 condition = column_obj .in_ (values )
108- elif rule .expression == RoleDataRuleExpressionType .not_in :
109- values = rule .value .split (',' ) if isinstance (rule .value , str ) else rule .value
117+ elif data_rule .expression == RoleDataRuleExpressionType .not_in :
118+ values = data_rule .value .split (',' ) if isinstance (data_rule .value , str ) else data_rule .value
110119 condition = ~ column_obj .in_ (values )
111120
112121 # 根据运算符添加到对应列表
113122 if condition is not None :
114- if rule .operator == RoleDataRuleOperatorType .AND :
123+ if data_rule .operator == RoleDataRuleOperatorType .AND :
115124 where_and_list .append (condition )
116- elif rule .operator == RoleDataRuleOperatorType .OR :
125+ elif data_rule .operator == RoleDataRuleOperatorType .OR :
117126 where_or_list .append (condition )
118127
119128 # 组合所有条件
0 commit comments