Skip to content

Commit 64f994c

Browse files
authored
Add more Casbin related interfaces (#195)
* Add more Casbin related interfaces * lint * update delete all api paths * fix decimal data format * update add user interface return * fix add user interface return * fix interface path is wrong * lint
1 parent c1295dd commit 64f994c

File tree

6 files changed

+150
-16
lines changed

6 files changed

+150
-16
lines changed

backend/app/api/v1/casbin.py

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
CreateUserRole,
1717
DeleteUserRole,
1818
GetAllPolicy,
19+
DeleteAllPolicies,
20+
DeleteAllUserRoles,
1921
)
2022
from backend.app.services.casbin_service import CasbinService
2123

@@ -33,13 +35,13 @@ async def get_all_casbin(
3335
return await response_base.success(data=page_data)
3436

3537

36-
@router.get('/policy', summary='获取所有访问权限规则', dependencies=[DependsJwtAuth])
38+
@router.get('/policy', summary='获取所有P权限规则', dependencies=[DependsJwtAuth])
3739
async def get_all_policies():
3840
policies = await CasbinService.get_policy_list()
3941
return await response_base.success(data=policies)
4042

4143

42-
@router.post('/policy', summary='添加访问权限', dependencies=[DependsRBAC])
44+
@router.post('/policy', summary='添加P权限规则', dependencies=[DependsRBAC])
4345
async def create_policy(p: CreatePolicy):
4446
"""
4547
p 规则:
@@ -54,25 +56,51 @@ async def create_policy(p: CreatePolicy):
5456
return await response_base.success(data=data)
5557

5658

57-
@router.put('/policy', summary='更新访问权限', dependencies=[DependsRBAC])
59+
@router.post('/policies', summary='添加多组P权限规则', dependencies=[DependsRBAC])
60+
async def create_policies(ps: list[CreatePolicy]):
61+
data = await CasbinService.create_policies(ps=ps)
62+
return await response_base.success(data=data)
63+
64+
65+
@router.put('/policy', summary='更新P权限规则', dependencies=[DependsRBAC])
5866
async def update_policy(old: UpdatePolicy, new: UpdatePolicy):
5967
data = await CasbinService.update_policy(old=old, new=new)
6068
return await response_base.success(data=data)
6169

6270

63-
@router.delete('/policy', summary='删除访问权限', dependencies=[DependsRBAC])
71+
@router.put('/policies', summary='更新多组P权限规则', dependencies=[DependsRBAC])
72+
async def update_policies(old: list[UpdatePolicy], new: list[UpdatePolicy]):
73+
data = await CasbinService.update_policies(old=old, new=new)
74+
return await response_base.success(data=data)
75+
76+
77+
@router.delete('/policy', summary='删除P权限规则', dependencies=[DependsRBAC])
6478
async def delete_policy(p: DeletePolicy):
6579
data = await CasbinService.delete_policy(p=p)
6680
return await response_base.success(data=data)
6781

6882

69-
@router.get('/group', summary='获取所有组访问权限规则', dependencies=[DependsJwtAuth])
83+
@router.delete('/policies', summary='删除多组P权限规则', dependencies=[DependsRBAC])
84+
async def delete_policies(ps: list[DeletePolicy]):
85+
data = await CasbinService.delete_policies(ps=ps)
86+
return await response_base.success(data=data)
87+
88+
89+
@router.delete('/policies/all', summary='删除所有P权限规则', dependencies=[DependsRBAC])
90+
async def delete_all_policies(sub: DeleteAllPolicies):
91+
count = await CasbinService.delete_all_policies(sub=sub)
92+
if count > 0:
93+
return await response_base.success()
94+
return await response_base.fail()
95+
96+
97+
@router.get('/group', summary='获取所有G权限规则', dependencies=[DependsJwtAuth])
7098
async def get_all_groups():
7199
data = await CasbinService.get_group_list()
72100
return await response_base.success(data=data)
73101

74102

75-
@router.post('/group', summary='添加组访问权限', dependencies=[DependsRBAC])
103+
@router.post('/group', summary='添加G权限规则', dependencies=[DependsRBAC])
76104
async def create_group(g: CreateUserRole):
77105
"""
78106
g 规则 (**依赖 p 规则**):
@@ -87,7 +115,27 @@ async def create_group(g: CreateUserRole):
87115
return await response_base.success(data=data)
88116

89117

90-
@router.delete('/group', summary='删除组访问权限', dependencies=[DependsRBAC])
118+
@router.post('/groups', summary='添加多组G权限规则', dependencies=[DependsRBAC])
119+
async def create_groups(gs: list[CreateUserRole]):
120+
data = await CasbinService.create_groups(gs=gs)
121+
return await response_base.success(data=data)
122+
123+
124+
@router.delete('/group', summary='删除G权限规则', dependencies=[DependsRBAC])
91125
async def delete_group(g: DeleteUserRole):
92126
data = await CasbinService.delete_group(g=g)
93127
return await response_base.success(data=data)
128+
129+
130+
@router.delete('/groups', summary='删除多组G权限规则', dependencies=[DependsRBAC])
131+
async def delete_groups(gs: list[DeleteUserRole]):
132+
data = await CasbinService.delete_groups(gs=gs)
133+
return await response_base.success(data=data)
134+
135+
136+
@router.delete('/groups/all', summary='删除所有G权限规则', dependencies=[DependsRBAC])
137+
async def delete_all_groups(uuid: DeleteAllUserRoles):
138+
count = await CasbinService.delete_all_groups(uuid=uuid)
139+
if count > 0:
140+
return await response_base.success()
141+
return await response_base.fail()

backend/app/api/v1/user.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ async def user_register(obj: RegisterUser):
3434
@router.post('/add', summary='添加用户', dependencies=[DependsRBAC])
3535
async def add_user(obj: AddUser):
3636
await UserService.add(obj=obj)
37-
return await response_base.success()
37+
current_user = await UserService.get_userinfo(username=obj.username)
38+
data = GetAllUserInfo(**select_to_json(current_user))
39+
return await response_base.success(data=data)
3840

3941

4042
@router.post('/password/reset', summary='密码重置', dependencies=[DependsJwtAuth])

backend/app/crud/crud_casbin.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
#!/usr/bin/env python3
22
# -*- coding: utf-8 -*-
3-
from sqlalchemy import Select, select, and_
3+
from sqlalchemy import Select, select, and_, delete, or_
4+
from sqlalchemy.ext.asyncio import AsyncSession
45

56
from backend.app.crud.base import CRUDBase
67
from backend.app.models import CasbinRule
7-
from backend.app.schemas.casbin_rule import CreatePolicy, UpdatePolicy
8+
from backend.app.schemas.casbin_rule import CreatePolicy, UpdatePolicy, DeleteAllPolicies, DeleteAllUserRoles
89

910

1011
class CRUDCasbin(CRUDBase[CasbinRule, CreatePolicy, UpdatePolicy]):
@@ -19,5 +20,17 @@ async def get_all_policy(self, ptype: str, sub: str) -> Select:
1920
se = se.where(and_(*where_list))
2021
return se
2122

23+
async def delete_policies_by_sub(self, db: AsyncSession, sub: DeleteAllPolicies) -> int:
24+
where_list = []
25+
if sub.uuid:
26+
where_list.append(self.model.v0 == sub.uuid)
27+
where_list.append(self.model.v0 == sub.role)
28+
result = await db.execute(delete(self.model).where(or_(*where_list)))
29+
return result.rowcount
30+
31+
async def delete_groups_by_uuid(self, db: AsyncSession, sub: DeleteAllUserRoles) -> int:
32+
result = await db.execute(delete(self.model).where(self.model.v0 == sub.uuid))
33+
return result.rowcount
34+
2235

2336
CasbinDao: CRUDCasbin = CRUDCasbin(CasbinRule)

backend/app/schemas/casbin_rule.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ class DeletePolicy(CreatePolicy):
2626
pass
2727

2828

29+
class DeleteAllPolicies(SchemaBase):
30+
uuid: str | None = None
31+
role: str
32+
33+
2934
class CreateUserRole(SchemaBase):
3035
uuid: str = Field(..., description='用户 uuid')
3136
role: str = Field(..., description='角色')
@@ -35,6 +40,10 @@ class DeleteUserRole(CreateUserRole):
3540
pass
3641

3742

43+
class DeleteAllUserRoles(SchemaBase):
44+
uuid: str
45+
46+
3847
class GetAllPolicy(SchemaBase):
3948
id: int
4049
ptype: str = Field(..., description='规则类型, p 或 g')

backend/app/services/casbin_service.py

Lines changed: 66 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,27 @@
55
from backend.app.common.rbac import RBAC
66
from backend.app.common.exception import errors
77
from backend.app.crud.crud_casbin import CasbinDao
8-
from backend.app.schemas.casbin_rule import CreatePolicy, UpdatePolicy, DeletePolicy, CreateUserRole, DeleteUserRole
8+
from backend.app.database.db_mysql import async_db_session
9+
from backend.app.schemas.casbin_rule import (
10+
CreatePolicy,
11+
UpdatePolicy,
12+
DeletePolicy,
13+
CreateUserRole,
14+
DeleteUserRole,
15+
DeleteAllPolicies,
16+
DeleteAllUserRoles,
17+
)
918

1019

1120
class CasbinService:
12-
1321
@staticmethod
1422
async def get_casbin_list(*, ptype: str, sub: str) -> Select:
1523
return await CasbinDao.get_all_policy(ptype, sub)
1624

1725
@staticmethod
1826
async def get_policy_list():
1927
enforcer = await RBAC.enforcer()
20-
data = enforcer.get_policy()
28+
data = await enforcer.get_policy()
2129
return data
2230

2331
@staticmethod
@@ -28,24 +36,54 @@ async def create_policy(*, p: CreatePolicy):
2836
raise errors.ForbiddenError(msg='权限已存在')
2937
return data
3038

39+
@staticmethod
40+
async def create_policies(*, ps: list[CreatePolicy]):
41+
enforcer = await RBAC.enforcer()
42+
data = await enforcer.add_policies([list(p.dict().values()) for p in ps])
43+
if not data:
44+
raise errors.ForbiddenError(msg='权限已存在')
45+
return data
46+
3147
@staticmethod
3248
async def update_policy(*, old: UpdatePolicy, new: UpdatePolicy):
3349
enforcer = await RBAC.enforcer()
34-
_p = await enforcer.has_named_policy('p', old.sub, old.path, old.method)
50+
_p = await enforcer.has_policy(old.sub, old.path, old.method)
3551
if not _p:
3652
raise errors.NotFoundError(msg='权限不存在')
3753
data = await enforcer.update_policy([old.sub, old.path, old.method], [new.sub, new.path, new.method])
3854
return data
3955

56+
@staticmethod
57+
async def update_policies(*, old: list[UpdatePolicy], new: list[UpdatePolicy]):
58+
enforcer = await RBAC.enforcer()
59+
data = await enforcer.update_policies(
60+
[list(o.dict().values()) for o in old], [list(n.dict().values()) for n in new]
61+
)
62+
return data
63+
4064
@staticmethod
4165
async def delete_policy(*, p: DeletePolicy):
4266
enforcer = await RBAC.enforcer()
43-
_p = await enforcer.has_named_policy('p', p.sub, p.path, p.method)
67+
_p = await enforcer.has_policy(p.sub, p.path, p.method)
4468
if not _p:
4569
raise errors.NotFoundError(msg='权限不存在')
4670
data = await enforcer.remove_policy(p.sub, p.path, p.method)
4771
return data
4872

73+
@staticmethod
74+
async def delete_policies(*, ps: list[DeletePolicy]):
75+
enforcer = await RBAC.enforcer()
76+
data = await enforcer.remove_policies([list(p.dict().values()) for p in ps])
77+
if not data:
78+
raise errors.NotFoundError(msg='权限不存在')
79+
return data
80+
81+
@staticmethod
82+
async def delete_all_policies(*, sub: DeleteAllPolicies) -> int:
83+
async with async_db_session.begin() as db:
84+
count = await CasbinDao.delete_policies_by_sub(db, sub)
85+
return count
86+
4987
@staticmethod
5088
async def get_group_list():
5189
enforcer = await RBAC.enforcer()
@@ -60,11 +98,33 @@ async def create_group(*, g: CreateUserRole):
6098
raise errors.ForbiddenError(msg='权限已存在')
6199
return data
62100

101+
@staticmethod
102+
async def create_groups(*, gs: list[CreateUserRole]):
103+
enforcer = await RBAC.enforcer()
104+
data = await enforcer.add_grouping_policies([list(g.dict().values()) for g in gs])
105+
if not data:
106+
raise errors.ForbiddenError(msg='权限已存在')
107+
return data
108+
63109
@staticmethod
64110
async def delete_group(*, g: DeleteUserRole):
65111
enforcer = await RBAC.enforcer()
66-
_g = await enforcer.has_named_grouping_policy('g', g.uuid, g.role)
112+
_g = await enforcer.has_grouping_policy(g.uuid, g.role)
67113
if not _g:
68114
raise errors.NotFoundError(msg='权限不存在')
69115
data = await enforcer.remove_grouping_policy(g.uuid, g.role)
70116
return data
117+
118+
@staticmethod
119+
async def delete_groups(*, gs: list[DeleteUserRole]):
120+
enforcer = await RBAC.enforcer()
121+
data = await enforcer.remove_grouping_policies([list(g.dict().values()) for g in gs])
122+
if not data:
123+
raise errors.NotFoundError(msg='权限不存在')
124+
return data
125+
126+
@staticmethod
127+
async def delete_all_groups(*, uuid: DeleteAllUserRoles) -> int:
128+
async with async_db_session.begin() as db:
129+
count = await CasbinDao.delete_groups_by_uuid(db, uuid)
130+
return count

backend/app/utils/serializers.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ def select_to_dict(row: R) -> dict:
2121
for column in row.__table__.columns.keys():
2222
val = getattr(row, column)
2323
if isinstance(val, Decimal):
24+
if val % 1 == 0:
25+
val = int(val)
2426
val = float(val)
2527
obj_dict[column] = val
2628
return obj_dict

0 commit comments

Comments
 (0)