mirror of
https://github.com/fastapi-practices/fastapi-best-architecture.git
synced 2026-09-21 21:15:13 +00:00
Update role-based data permissions (#465)
* Add department data operation permissions * Update sys models * Add role department many-to-many relationship * Format RBAC code * update codes * add update role depts api * add comments * Update the implementation * update dept arg * debug front * Update the model file naming * Refactor the data perms * Add data permission rule * Optimize the details * Implement data filtering * finish
This commit is contained in:
@@ -21,7 +21,7 @@ class RBAC:
|
||||
|
||||
:return:
|
||||
"""
|
||||
# 规则数据作为死数据直接在方法内定义
|
||||
# 模型定义:https://casbin.org/zh/docs/category/model
|
||||
_CASBIN_RBAC_MODEL_CONF_TEXT = """
|
||||
[request_definition]
|
||||
r = sub, obj, act
|
||||
@@ -46,56 +46,69 @@ class RBAC:
|
||||
|
||||
async def rbac_verify(self, request: Request, _token: str = DependsJwtAuth) -> None:
|
||||
"""
|
||||
RBAC 权限校验
|
||||
RBAC 权限校验(鉴权顺序很重要,谨慎修改)
|
||||
|
||||
:param request:
|
||||
:param _token:
|
||||
:return:
|
||||
"""
|
||||
path = request.url.path
|
||||
# 鉴权白名单
|
||||
|
||||
# API 鉴权白名单
|
||||
if path in settings.TOKEN_REQUEST_PATH_EXCLUDE:
|
||||
return
|
||||
|
||||
# JWT 授权状态强制校验
|
||||
if not request.auth.scopes:
|
||||
raise TokenError
|
||||
|
||||
# 超级管理员免校验
|
||||
if request.user.is_superuser:
|
||||
return
|
||||
# 检测角色数据权限范围
|
||||
|
||||
# 检测用户角色
|
||||
user_roles = request.user.roles
|
||||
if not user_roles:
|
||||
raise AuthorizationError(msg='用户未分配角色,授权失败')
|
||||
if not user_roles or all(status == 0 for status in user_roles):
|
||||
raise AuthorizationError(msg='用户未分配角色,请联系系统管理员')
|
||||
|
||||
# 检测用户所属角色菜单
|
||||
if not any(len(role.menus) > 0 for role in user_roles):
|
||||
raise AuthorizationError(msg='用户所属角色未分配菜单,授权失败')
|
||||
raise AuthorizationError(msg='用户未分配菜单,请联系系统管理员')
|
||||
|
||||
# 检测后台管理操作权限
|
||||
method = request.method
|
||||
if method != MethodType.GET or method != MethodType.OPTIONS:
|
||||
if not request.user.is_staff:
|
||||
raise AuthorizationError(msg='此用户已被禁止后台管理操作')
|
||||
# 数据权限范围
|
||||
data_scope = any(role.data_scope == 1 for role in user_roles)
|
||||
if data_scope:
|
||||
return
|
||||
user_uuid = request.user.uuid
|
||||
raise AuthorizationError(msg='用户已被禁止后台管理操作,请联系系统管理员')
|
||||
|
||||
# RBAC 鉴权
|
||||
if settings.PERMISSION_MODE == 'role-menu':
|
||||
# 角色菜单权限校验
|
||||
path_auth_perm = getattr(request.state, 'permission', None)
|
||||
# 没有菜单权限标识不校验
|
||||
|
||||
# 没有菜单操作权限标识不校验
|
||||
if not path_auth_perm:
|
||||
return
|
||||
if path_auth_perm in set(settings.RBAC_ROLE_MENU_EXCLUDE):
|
||||
|
||||
# 菜单鉴权白名单
|
||||
if path_auth_perm in settings.RBAC_ROLE_MENU_EXCLUDE:
|
||||
return
|
||||
|
||||
# 已分配菜单权限校验
|
||||
allow_perms = []
|
||||
for role in user_roles:
|
||||
for menu in role.menus:
|
||||
if menu.status == StatusType.enable:
|
||||
if menu.perms and menu.status == StatusType.enable:
|
||||
allow_perms.extend(menu.perms.split(','))
|
||||
if path_auth_perm not in allow_perms:
|
||||
raise AuthorizationError
|
||||
else:
|
||||
# casbin 权限校验
|
||||
# casbin 鉴权白名单
|
||||
if (method, path) in settings.RBAC_CASBIN_EXCLUDE:
|
||||
return
|
||||
|
||||
# casbin 权限校验
|
||||
# 实现机制:backend/app/admin/api/v1/sys/casbin.py
|
||||
user_uuid = request.user.uuid
|
||||
enforcer = await self.enforcer()
|
||||
if not enforcer.enforce(user_uuid, path, method):
|
||||
raise AuthorizationError
|
||||
|
||||
Reference in New Issue
Block a user