springbootAI 1.8.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- spring/__init__.py +66 -0
- spring/ai/__init__.py +78 -0
- spring/ai/advisors.py +139 -0
- spring/ai/annotations.py +74 -0
- spring/ai/autoconfig.py +481 -0
- spring/ai/core.py +391 -0
- spring/ai/etl.py +188 -0
- spring/ai/memory.py +109 -0
- spring/ai/observability.py +129 -0
- spring/ai/providers.py +789 -0
- spring/ai/resilience.py +258 -0
- spring/ai/tools.py +106 -0
- spring/ai/vectorstore.py +303 -0
- spring/annotations/__init__.py +188 -0
- spring/annotations/cache.py +126 -0
- spring/annotations/cloud.py +207 -0
- spring/annotations/conditional.py +272 -0
- spring/annotations/core.py +864 -0
- spring/annotations/messaging.py +107 -0
- spring/aop/__init__.py +4 -0
- spring/aop/cloud_aop.py +404 -0
- spring/aop/comprehensive_aop.py +1015 -0
- spring/aop/method_interceptor.py +19 -0
- spring/aop/proxy_factory.py +55 -0
- spring/cloud/__init__.py +76 -0
- spring/cloud/discovery.py +364 -0
- spring/cloud/feign.py +469 -0
- spring/cloud/gateway.py +452 -0
- spring/cloud/load_balancer.py +149 -0
- spring/cloud/seata.py +557 -0
- spring/cloud/sentinel.py +525 -0
- spring/cloud/tracer.py +337 -0
- spring/config/__init__.py +21 -0
- spring/config/binding.py +206 -0
- spring/config/config_loader.py +405 -0
- spring/context/__init__.py +13 -0
- spring/context/application_context.py +589 -0
- spring/context/bean_definition.py +70 -0
- spring/context/bean_factory.py +1052 -0
- spring/context/registry.py +58 -0
- spring/context/scanner.py +106 -0
- spring/core/__init__.py +3 -0
- spring/core/graceful_shutdown.py +196 -0
- spring/core/typing_utils.py +50 -0
- spring/csv/__init__.py +52 -0
- spring/csv/annotations.py +402 -0
- spring/csv/converters.py +69 -0
- spring/csv/easy_csv.py +95 -0
- spring/csv/exceptions.py +27 -0
- spring/csv/reader.py +195 -0
- spring/csv/writer.py +155 -0
- spring/data/__init__.py +54 -0
- spring/data/page.py +181 -0
- spring/data/repository.py +274 -0
- spring/data/specification.py +228 -0
- spring/datasource/__init__.py +66 -0
- spring/datasource/annotations.py +133 -0
- spring/datasource/context.py +69 -0
- spring/datasource/dynamic.py +148 -0
- spring/event/__init__.py +7 -0
- spring/event/publisher.py +69 -0
- spring/excel/__init__.py +51 -0
- spring/excel/annotations.py +405 -0
- spring/excel/converters.py +231 -0
- spring/excel/easy_excel.py +94 -0
- spring/excel/exceptions.py +31 -0
- spring/excel/reader.py +254 -0
- spring/excel/style.py +95 -0
- spring/excel/writer.py +197 -0
- spring/i18n/__init__.py +97 -0
- spring/i18n/accessor.py +94 -0
- spring/i18n/auto_config.py +177 -0
- spring/i18n/holder.py +106 -0
- spring/i18n/locale.py +152 -0
- spring/i18n/locale_resolver.py +367 -0
- spring/i18n/message_source.py +250 -0
- spring/i18n/middleware.py +79 -0
- spring/i18n/properties.py +168 -0
- spring/i18n/sources.py +255 -0
- spring/logging/__init__.py +1 -0
- spring/logging/loguru_logger.py +228 -0
- spring/main.py +378 -0
- spring/messaging/__init__.py +1 -0
- spring/messaging/rabbitmq.py +302 -0
- spring/monitoring/__init__.py +1 -0
- spring/monitoring/prometheus.py +199 -0
- spring/orm/__init__.py +258 -0
- spring/orm/database.py +222 -0
- spring/orm/ddl_auto.py +1217 -0
- spring/orm/migration.py +419 -0
- spring/orm/mybatis_integration.py +400 -0
- spring/orm/pymybatis/__init__.py +86 -0
- spring/orm/pymybatis/annotations/__init__.py +30 -0
- spring/orm/pymybatis/annotations/annotations.py +332 -0
- spring/orm/pymybatis/cache/__init__.py +47 -0
- spring/orm/pymybatis/cache/cache.py +371 -0
- spring/orm/pymybatis/cache/redis_cache.py +434 -0
- spring/orm/pymybatis/circuit_breaker/__init__.py +21 -0
- spring/orm/pymybatis/circuit_breaker/circuit_breaker.py +424 -0
- spring/orm/pymybatis/configuration.py +525 -0
- spring/orm/pymybatis/core/__init__.py +10 -0
- spring/orm/pymybatis/core/sql_session.py +1382 -0
- spring/orm/pymybatis/core/sql_session_factory.py +76 -0
- spring/orm/pymybatis/dialect/__init__.py +9 -0
- spring/orm/pymybatis/dialect/dialect.py +445 -0
- spring/orm/pymybatis/dynamic_sql/__init__.py +9 -0
- spring/orm/pymybatis/dynamic_sql/dynamic_sql.py +900 -0
- spring/orm/pymybatis/interceptor/__init__.py +31 -0
- spring/orm/pymybatis/interceptor/interceptor.py +427 -0
- spring/orm/pymybatis/mapper/__init__.py +9 -0
- spring/orm/pymybatis/mapper/mapper.py +540 -0
- spring/orm/pymybatis/metrics/__init__.py +41 -0
- spring/orm/pymybatis/metrics/metrics.py +595 -0
- spring/orm/pymybatis/pool/__init__.py +9 -0
- spring/orm/pymybatis/pool/connection_pool.py +711 -0
- spring/orm/pymybatis/security/__init__.py +19 -0
- spring/orm/pymybatis/security/access_control.py +415 -0
- spring/orm/pymybatis/security/password_encoder.py +293 -0
- spring/orm/pymybatis/security/sensitive_data_masker.py +326 -0
- spring/orm/pymybatis/security/sql_injection_detector.py +675 -0
- spring/orm/pymybatis/transaction/__init__.py +9 -0
- spring/orm/pymybatis/transaction/transaction.py +288 -0
- spring/orm/pymybatis/type_handler/__init__.py +37 -0
- spring/orm/pymybatis/type_handler/type_handler.py +473 -0
- spring/orm/pymybatis/version.py +9 -0
- spring/orm/pymybatis/xml_parser/__init__.py +9 -0
- spring/orm/pymybatis/xml_parser/xml_parser.py +761 -0
- spring/retry/__init__.py +12 -0
- spring/retry/retry_annotations.py +71 -0
- spring/retry/retry_decorator.py +155 -0
- spring/scheduling/__init__.py +3 -0
- spring/scheduling/scheduler.py +389 -0
- spring/security/__init__.py +39 -0
- spring/security/jwt_utils.py +281 -0
- spring/security/replay_protection.py +206 -0
- spring/security/secret_manager.py +226 -0
- spring/security/security_aop.py +248 -0
- spring/security/security_context.py +172 -0
- spring/test/__init__.py +45 -0
- spring/test/slicing.py +341 -0
- spring/tracing/__init__.py +11 -0
- spring/tracing/skywalking.py +229 -0
- spring/tx/__init__.py +52 -0
- spring/tx/events.py +172 -0
- spring/tx/synchronization.py +143 -0
- spring/utils/__init__.py +5 -0
- spring/utils/banner.py +32 -0
- spring/utils/logger.py +73 -0
- spring/utils/redis_client.py +526 -0
- spring/validation/__init__.py +55 -0
- spring/validation/aop.py +141 -0
- spring/validation/constraints.py +357 -0
- spring/validation/exceptions.py +55 -0
- spring/validation/validator.py +139 -0
- spring/web/__init__.py +12 -0
- spring/web/actuator.py +319 -0
- spring/web/exception_handler.py +61 -0
- spring/web/health.py +399 -0
- spring/web/interceptor.py +91 -0
- spring/web/result.py +44 -0
- spring/web/swagger.py +601 -0
- spring/web/web_context.py +755 -0
- spring/websocket/__init__.py +86 -0
- spring/websocket/annotations.py +169 -0
- spring/websocket/broker.py +238 -0
- spring/websocket/exceptions.py +26 -0
- spring/websocket/handler.py +243 -0
- spring/websocket/router.py +526 -0
- spring/websocket/session.py +216 -0
- springbootai-1.8.0.dist-info/METADATA +2796 -0
- springbootai-1.8.0.dist-info/RECORD +175 -0
- springbootai-1.8.0.dist-info/WHEEL +5 -0
- springbootai-1.8.0.dist-info/entry_points.txt +2 -0
- springbootai-1.8.0.dist-info/licenses/LICENSE +7 -0
- springbootai-1.8.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""
|
|
2
|
+
PyMyBatis安全模块
|
|
3
|
+
|
|
4
|
+
包含SQL注入防御、敏感数据脱敏、访问控制、密码加密等安全组件
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .sql_injection_detector import SQLInjectionDetector
|
|
8
|
+
from .sensitive_data_masker import SensitiveDataMasker
|
|
9
|
+
from .access_control import AccessControl, RoleBasedAccessControl, RowLevelAccessControl
|
|
10
|
+
from .password_encoder import PasswordEncoder
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
'SQLInjectionDetector',
|
|
14
|
+
'SensitiveDataMasker',
|
|
15
|
+
'AccessControl',
|
|
16
|
+
'RoleBasedAccessControl',
|
|
17
|
+
'RowLevelAccessControl',
|
|
18
|
+
'PasswordEncoder'
|
|
19
|
+
]
|
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
"""
|
|
2
|
+
PyMyBatis访问控制模块
|
|
3
|
+
|
|
4
|
+
实现防止越权查询的访问控制机制
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Dict, Optional, Any, Callable
|
|
8
|
+
from abc import ABC, abstractmethod
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class AccessControlRule:
|
|
12
|
+
"""
|
|
13
|
+
访问控制规则
|
|
14
|
+
|
|
15
|
+
定义对特定表/字段的访问权限
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def __init__(self, table: str, action: str, condition: Optional[Callable] = None, fields: Optional[list] = None):
|
|
19
|
+
"""
|
|
20
|
+
初始化访问控制规则
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
table: 表名
|
|
24
|
+
action: 操作类型(SELECT/INSERT/UPDATE/DELETE)
|
|
25
|
+
condition: 访问条件函数,返回额外的WHERE条件
|
|
26
|
+
fields: 允许访问的字段列表,None表示全部允许
|
|
27
|
+
"""
|
|
28
|
+
self.table = table
|
|
29
|
+
self.action = action.upper()
|
|
30
|
+
self.condition = condition
|
|
31
|
+
self.fields = fields or []
|
|
32
|
+
|
|
33
|
+
def check_access(self, user_context: Dict[str, Any], params: Dict[str, Any]) -> bool:
|
|
34
|
+
"""
|
|
35
|
+
检查访问权限
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
user_context: 用户上下文(包含用户ID、角色等)
|
|
39
|
+
params: 查询参数
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
是否允许访问
|
|
43
|
+
"""
|
|
44
|
+
if self.condition is None:
|
|
45
|
+
return True
|
|
46
|
+
|
|
47
|
+
return self.condition(user_context, params)
|
|
48
|
+
|
|
49
|
+
def get_access_condition(self, user_context: Dict[str, Any]) -> Optional[str]:
|
|
50
|
+
"""
|
|
51
|
+
获取访问条件
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
user_context: 用户上下文
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
WHERE条件字符串,无条件返回None
|
|
58
|
+
"""
|
|
59
|
+
if self.condition is None:
|
|
60
|
+
return None
|
|
61
|
+
|
|
62
|
+
return self.condition(user_context, {})
|
|
63
|
+
|
|
64
|
+
def check_fields(self, fields: list) -> list:
|
|
65
|
+
"""
|
|
66
|
+
检查字段访问权限
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
fields: 请求访问的字段列表
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
允许访问的字段列表
|
|
73
|
+
"""
|
|
74
|
+
if not self.fields:
|
|
75
|
+
return fields
|
|
76
|
+
|
|
77
|
+
return [f for f in fields if f in self.fields]
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class AccessControl(ABC):
|
|
81
|
+
"""
|
|
82
|
+
访问控制抽象基类
|
|
83
|
+
|
|
84
|
+
定义访问控制的核心接口
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
@abstractmethod
|
|
88
|
+
def check_access(self, table: str, action: str, user_context: Dict[str, Any], params: Dict[str, Any]) -> bool:
|
|
89
|
+
"""
|
|
90
|
+
检查访问权限
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
table: 表名
|
|
94
|
+
action: 操作类型
|
|
95
|
+
user_context: 用户上下文
|
|
96
|
+
params: 查询参数
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
是否允许访问
|
|
100
|
+
"""
|
|
101
|
+
pass
|
|
102
|
+
|
|
103
|
+
@abstractmethod
|
|
104
|
+
def get_access_condition(self, table: str, action: str, user_context: Dict[str, Any]) -> Optional[str]:
|
|
105
|
+
"""
|
|
106
|
+
获取访问条件
|
|
107
|
+
|
|
108
|
+
Args:
|
|
109
|
+
table: 表名
|
|
110
|
+
action: 操作类型
|
|
111
|
+
user_context: 用户上下文
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
WHERE条件字符串
|
|
115
|
+
"""
|
|
116
|
+
pass
|
|
117
|
+
|
|
118
|
+
@abstractmethod
|
|
119
|
+
def check_fields(self, table: str, action: str, fields: list) -> list:
|
|
120
|
+
"""
|
|
121
|
+
检查字段访问权限
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
table: 表名
|
|
125
|
+
action: 操作类型
|
|
126
|
+
fields: 请求访问的字段列表
|
|
127
|
+
|
|
128
|
+
Returns:
|
|
129
|
+
允许访问的字段列表
|
|
130
|
+
"""
|
|
131
|
+
pass
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
class RoleBasedAccessControl(AccessControl):
|
|
135
|
+
"""
|
|
136
|
+
基于角色的访问控制(RBAC)
|
|
137
|
+
|
|
138
|
+
根据用户角色控制对表和字段的访问权限
|
|
139
|
+
"""
|
|
140
|
+
|
|
141
|
+
def __init__(self, enabled: bool = False):
|
|
142
|
+
"""
|
|
143
|
+
初始化RBAC控制器
|
|
144
|
+
|
|
145
|
+
Args:
|
|
146
|
+
enabled: 是否启用访问控制
|
|
147
|
+
"""
|
|
148
|
+
self.enabled = enabled
|
|
149
|
+
self.rules: Dict[str, Dict[str, AccessControlRule]] = {}
|
|
150
|
+
self.default_rules: Dict[str, AccessControlRule] = {}
|
|
151
|
+
|
|
152
|
+
def add_rule(self, role: str, table: str, action: str, condition: Optional[Callable] = None, fields: Optional[list] = None) -> None:
|
|
153
|
+
"""
|
|
154
|
+
添加角色访问规则
|
|
155
|
+
|
|
156
|
+
Args:
|
|
157
|
+
role: 角色名称
|
|
158
|
+
table: 表名
|
|
159
|
+
action: 操作类型
|
|
160
|
+
condition: 访问条件
|
|
161
|
+
fields: 允许访问的字段
|
|
162
|
+
"""
|
|
163
|
+
if role not in self.rules:
|
|
164
|
+
self.rules[role] = {}
|
|
165
|
+
|
|
166
|
+
key = f"{table}_{action}"
|
|
167
|
+
self.rules[role][key] = AccessControlRule(table, action, condition, fields)
|
|
168
|
+
|
|
169
|
+
def set_default_rule(self, table: str, action: str, condition: Optional[Callable] = None, fields: Optional[list] = None) -> None:
|
|
170
|
+
"""
|
|
171
|
+
设置默认规则(当没有匹配的角色规则时使用)
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
table: 表名
|
|
175
|
+
action: 操作类型
|
|
176
|
+
condition: 访问条件
|
|
177
|
+
fields: 允许访问的字段
|
|
178
|
+
"""
|
|
179
|
+
key = f"{table}_{action}"
|
|
180
|
+
self.default_rules[key] = AccessControlRule(table, action, condition, fields)
|
|
181
|
+
|
|
182
|
+
def _get_rule(self, role: str, table: str, action: str) -> Optional[AccessControlRule]:
|
|
183
|
+
"""
|
|
184
|
+
获取匹配的规则
|
|
185
|
+
|
|
186
|
+
Args:
|
|
187
|
+
role: 角色名称
|
|
188
|
+
table: 表名
|
|
189
|
+
action: 操作类型
|
|
190
|
+
|
|
191
|
+
Returns:
|
|
192
|
+
匹配的规则,无匹配返回None
|
|
193
|
+
"""
|
|
194
|
+
if not self.enabled:
|
|
195
|
+
return None
|
|
196
|
+
|
|
197
|
+
key = f"{table}_{action}"
|
|
198
|
+
|
|
199
|
+
# 先查找角色特定规则
|
|
200
|
+
if role in self.rules and key in self.rules[role]:
|
|
201
|
+
return self.rules[role][key]
|
|
202
|
+
|
|
203
|
+
# 再查找默认规则
|
|
204
|
+
if key in self.default_rules:
|
|
205
|
+
return self.default_rules[key]
|
|
206
|
+
|
|
207
|
+
return None
|
|
208
|
+
|
|
209
|
+
def check_access(self, table: str, action: str, user_context: Dict[str, Any], params: Dict[str, Any]) -> bool:
|
|
210
|
+
"""
|
|
211
|
+
检查访问权限
|
|
212
|
+
|
|
213
|
+
Args:
|
|
214
|
+
table: 表名
|
|
215
|
+
action: 操作类型
|
|
216
|
+
user_context: 用户上下文(包含user_id、role等)
|
|
217
|
+
params: 查询参数
|
|
218
|
+
|
|
219
|
+
Returns:
|
|
220
|
+
是否允许访问
|
|
221
|
+
"""
|
|
222
|
+
if not self.enabled:
|
|
223
|
+
return True
|
|
224
|
+
|
|
225
|
+
role = user_context.get('role', 'guest')
|
|
226
|
+
rule = self._get_rule(role, table, action)
|
|
227
|
+
|
|
228
|
+
if rule is None:
|
|
229
|
+
# 默认拒绝访问(安全优先)
|
|
230
|
+
return False
|
|
231
|
+
|
|
232
|
+
return rule.check_access(user_context, params)
|
|
233
|
+
|
|
234
|
+
def get_access_condition(self, table: str, action: str, user_context: Dict[str, Any]) -> Optional[str]:
|
|
235
|
+
"""
|
|
236
|
+
获取访问条件
|
|
237
|
+
|
|
238
|
+
Args:
|
|
239
|
+
table: 表名
|
|
240
|
+
action: 操作类型
|
|
241
|
+
user_context: 用户上下文
|
|
242
|
+
|
|
243
|
+
Returns:
|
|
244
|
+
WHERE条件字符串
|
|
245
|
+
"""
|
|
246
|
+
if not self.enabled:
|
|
247
|
+
return None
|
|
248
|
+
|
|
249
|
+
role = user_context.get('role', 'guest')
|
|
250
|
+
rule = self._get_rule(role, table, action)
|
|
251
|
+
|
|
252
|
+
if rule is None:
|
|
253
|
+
return None
|
|
254
|
+
|
|
255
|
+
return rule.get_access_condition(user_context)
|
|
256
|
+
|
|
257
|
+
def check_fields(self, table: str, action: str, fields: list) -> list:
|
|
258
|
+
"""
|
|
259
|
+
检查字段访问权限
|
|
260
|
+
|
|
261
|
+
Args:
|
|
262
|
+
table: 表名
|
|
263
|
+
action: 操作类型
|
|
264
|
+
fields: 请求访问的字段列表
|
|
265
|
+
|
|
266
|
+
Returns:
|
|
267
|
+
允许访问的字段列表
|
|
268
|
+
"""
|
|
269
|
+
if not self.enabled:
|
|
270
|
+
return fields
|
|
271
|
+
|
|
272
|
+
# 对于SELECT操作,检查字段访问权限
|
|
273
|
+
if action.upper() != 'SELECT':
|
|
274
|
+
return fields
|
|
275
|
+
|
|
276
|
+
# 获取用户角色
|
|
277
|
+
# 这里需要从上下文中获取角色,但在字段检查时可能没有用户上下文
|
|
278
|
+
# 因此默认检查所有规则中对该表的字段限制
|
|
279
|
+
allowed_fields = set(fields)
|
|
280
|
+
|
|
281
|
+
for role_rules in self.rules.values():
|
|
282
|
+
key = f"{table}_{action}"
|
|
283
|
+
if key in role_rules:
|
|
284
|
+
rule = role_rules[key]
|
|
285
|
+
if rule.fields:
|
|
286
|
+
allowed_fields = allowed_fields.intersection(set(rule.fields))
|
|
287
|
+
|
|
288
|
+
# 检查默认规则
|
|
289
|
+
key = f"{table}_{action}"
|
|
290
|
+
if key in self.default_rules:
|
|
291
|
+
rule = self.default_rules[key]
|
|
292
|
+
if rule.fields:
|
|
293
|
+
allowed_fields = allowed_fields.intersection(set(rule.fields))
|
|
294
|
+
|
|
295
|
+
return list(allowed_fields)
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
class RowLevelAccessControl(AccessControl):
|
|
299
|
+
"""
|
|
300
|
+
行级访问控制
|
|
301
|
+
|
|
302
|
+
根据用户上下文限制只能访问特定行的数据
|
|
303
|
+
"""
|
|
304
|
+
|
|
305
|
+
def __init__(self, enabled: bool = False):
|
|
306
|
+
"""
|
|
307
|
+
初始化行级访问控制器
|
|
308
|
+
|
|
309
|
+
Args:
|
|
310
|
+
enabled: 是否启用访问控制
|
|
311
|
+
"""
|
|
312
|
+
self.enabled = enabled
|
|
313
|
+
self.row_filters: Dict[str, Callable] = {}
|
|
314
|
+
|
|
315
|
+
def set_row_filter(self, table: str, filter_func: Callable) -> None:
|
|
316
|
+
"""
|
|
317
|
+
设置行过滤函数
|
|
318
|
+
|
|
319
|
+
Args:
|
|
320
|
+
table: 表名
|
|
321
|
+
filter_func: 过滤函数,接收用户上下文返回WHERE条件
|
|
322
|
+
"""
|
|
323
|
+
self.row_filters[table] = filter_func
|
|
324
|
+
|
|
325
|
+
def check_access(self, table: str, action: str, user_context: Dict[str, Any], params: Dict[str, Any]) -> bool:
|
|
326
|
+
"""
|
|
327
|
+
检查访问权限
|
|
328
|
+
|
|
329
|
+
Args:
|
|
330
|
+
table: 表名
|
|
331
|
+
action: 操作类型
|
|
332
|
+
user_context: 用户上下文
|
|
333
|
+
params: 查询参数
|
|
334
|
+
|
|
335
|
+
Returns:
|
|
336
|
+
是否允许访问
|
|
337
|
+
"""
|
|
338
|
+
if not self.enabled:
|
|
339
|
+
return True
|
|
340
|
+
|
|
341
|
+
# 行级访问控制主要通过条件过滤实现,这里默认允许
|
|
342
|
+
return True
|
|
343
|
+
|
|
344
|
+
def get_access_condition(self, table: str, action: str, user_context: Dict[str, Any]) -> Optional[str]:
|
|
345
|
+
"""
|
|
346
|
+
获取访问条件
|
|
347
|
+
|
|
348
|
+
Args:
|
|
349
|
+
table: 表名
|
|
350
|
+
action: 操作类型
|
|
351
|
+
user_context: 用户上下文
|
|
352
|
+
|
|
353
|
+
Returns:
|
|
354
|
+
WHERE条件字符串
|
|
355
|
+
"""
|
|
356
|
+
if not self.enabled:
|
|
357
|
+
return None
|
|
358
|
+
|
|
359
|
+
if table in self.row_filters:
|
|
360
|
+
return self.row_filters[table](user_context)
|
|
361
|
+
|
|
362
|
+
return None
|
|
363
|
+
|
|
364
|
+
def check_fields(self, table: str, action: str, fields: list) -> list:
|
|
365
|
+
"""
|
|
366
|
+
检查字段访问权限
|
|
367
|
+
|
|
368
|
+
Args:
|
|
369
|
+
table: 表名
|
|
370
|
+
action: 操作类型
|
|
371
|
+
fields: 请求访问的字段列表
|
|
372
|
+
|
|
373
|
+
Returns:
|
|
374
|
+
允许访问的字段列表
|
|
375
|
+
"""
|
|
376
|
+
if not self.enabled:
|
|
377
|
+
return fields
|
|
378
|
+
|
|
379
|
+
# 行级访问控制不限制字段
|
|
380
|
+
return fields
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
# 全局默认访问控制器
|
|
384
|
+
DEFAULT_ACCESS_CONTROL = RoleBasedAccessControl()
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
def check_table_access(table: str, action: str, user_context: Dict[str, Any], params: Dict[str, Any]) -> bool:
|
|
388
|
+
"""
|
|
389
|
+
便捷函数:检查表访问权限
|
|
390
|
+
|
|
391
|
+
Args:
|
|
392
|
+
table: 表名
|
|
393
|
+
action: 操作类型
|
|
394
|
+
user_context: 用户上下文
|
|
395
|
+
params: 查询参数
|
|
396
|
+
|
|
397
|
+
Returns:
|
|
398
|
+
是否允许访问
|
|
399
|
+
"""
|
|
400
|
+
return DEFAULT_ACCESS_CONTROL.check_access(table, action, user_context, params)
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
def get_row_level_condition(table: str, action: str, user_context: Dict[str, Any]) -> Optional[str]:
|
|
404
|
+
"""
|
|
405
|
+
便捷函数:获取行级访问条件
|
|
406
|
+
|
|
407
|
+
Args:
|
|
408
|
+
table: 表名
|
|
409
|
+
action: 操作类型
|
|
410
|
+
user_context: 用户上下文
|
|
411
|
+
|
|
412
|
+
Returns:
|
|
413
|
+
WHERE条件字符串
|
|
414
|
+
"""
|
|
415
|
+
return DEFAULT_ACCESS_CONTROL.get_access_condition(table, action, user_context)
|