4
4
from fastapi import APIRouter , Depends , HTTPException , Form
5
5
from fastapi .responses import RedirectResponse
6
6
from pydantic import BaseModel , ConfigDict
7
- from sqlmodel import Session , select
7
+ from sqlmodel import Session , select , delete
8
8
from utils .db import Role , RolePermissionLink , ValidPermissions , get_session , utc_time
9
9
10
10
logger = getLogger ("uvicorn.error" )
@@ -37,12 +37,13 @@ class RoleRead(BaseModel):
37
37
class RoleUpdate (BaseModel ):
38
38
model_config = ConfigDict (from_attributes = True )
39
39
40
+ id : int
40
41
name : str
41
42
permissions : List [ValidPermissions ]
42
43
43
44
@classmethod
44
- async def as_form (cls , name : str = Form (...), permissions : List [ValidPermissions ] = Form (...)):
45
- return cls (name = name , permissions = permissions )
45
+ async def as_form (cls , id : int = Form (...), name : str = Form (...), permissions : List [ValidPermissions ] = Form (...)):
46
+ return cls (id = id , name = name , permissions = permissions )
46
47
47
48
48
49
@router .post ("/" , response_class = RedirectResponse )
@@ -56,30 +57,29 @@ def create_role(
56
57
57
58
# Create role and permissions in a single transaction
58
59
db_role = Role (name = role .name )
59
- session .add (db_role )
60
- session .commit ()
61
- session .refresh (db_role )
62
60
63
- for permission in role .permissions :
64
- db_role_permission_link = RolePermissionLink (
65
- role_id = db_role .id ,
66
- permission_id = permission .name
67
- )
68
- session .add (db_role_permission_link )
69
- session .commit ()
61
+ # Create RolePermissionLink objects and associate them with the role
62
+ db_role .permissions = [
63
+ RolePermissionLink (permission_id = permission .name )
64
+ for permission in role .permissions
65
+ ]
66
+
67
+ session .add (db_role )
68
+ session .commit () # Commit once after all operations
70
69
71
70
return RedirectResponse (url = "/roles" , status_code = 303 )
72
71
73
72
74
73
@router .get ("/{role_id}" , response_model = RoleRead )
75
74
def read_role (role_id : int , session : Session = Depends (get_session )):
76
- db_role = session .get (Role , role_id )
77
- if not db_role :
75
+ db_role : Role | None = session .get (Role , role_id )
76
+ if not db_role or not db_role . id or db_role . deleted :
78
77
raise HTTPException (status_code = 404 , detail = "Role not found" )
79
78
80
79
permissions = [
81
80
ValidPermissions (link .permission .name )
82
81
for link in db_role .role_permission_links
82
+ if link .permission is not None
83
83
]
84
84
85
85
return RoleRead (
@@ -94,12 +94,11 @@ def read_role(role_id: int, session: Session = Depends(get_session)):
94
94
95
95
@router .put ("/{role_id}" , response_class = RedirectResponse )
96
96
def update_role (
97
- role_id : int ,
98
97
role : RoleUpdate = Depends (RoleUpdate .as_form ),
99
98
session : Session = Depends (get_session )
100
99
) -> RedirectResponse :
101
- db_role = session .get (Role , role_id )
102
- if not db_role :
100
+ db_role : Role | None = session .get (Role , role . id )
101
+ if not db_role or not db_role . id or db_role . deleted :
103
102
raise HTTPException (status_code = 404 , detail = "Role not found" )
104
103
role_data = role .model_dump (exclude_unset = True )
105
104
for key , value in role_data .items ():
@@ -108,9 +107,8 @@ def update_role(
108
107
session .add (db_role )
109
108
session .commit ()
110
109
111
- # Update RolePermissionLinks
112
- session .exec (select (RolePermissionLink ).where (
113
- RolePermissionLink .role_id == role_id )).delete ()
110
+ # Correctly delete RolePermissionLinks for the role
111
+ session .delete (RolePermissionLink .role_id == role .id )
114
112
115
113
for permission in role .permissions :
116
114
db_role_permission_link = RolePermissionLink (
@@ -121,7 +119,7 @@ def update_role(
121
119
122
120
session .commit ()
123
121
session .refresh (db_role )
124
- return RedirectResponse (url = f"/roles/{ role_id } " , status_code = 303 )
122
+ return RedirectResponse (url = f"/roles/{ role . id } " , status_code = 303 )
125
123
126
124
127
125
@router .delete ("/{role_id}" , response_class = RedirectResponse )
0 commit comments