5
5
from sqlmodel import Session , select
6
6
from utils .db import get_session
7
7
from utils .auth import get_authenticated_user
8
- from utils .models import Organization , User
8
+ from utils .models import Organization , User , Role , UserOrganizationLink , ValidPermissions , RolePermissionLink , Permission
9
9
from datetime import datetime
10
+ from sqlalchemy import and_
10
11
11
12
logger = getLogger ("uvicorn.error" )
12
13
@@ -45,6 +46,14 @@ def __init__(self):
45
46
)
46
47
47
48
49
+ class InsufficientPermissionsError (HTTPException ):
50
+ def __init__ (self ):
51
+ super ().__init__ (
52
+ status_code = 403 ,
53
+ detail = "You don't have permission to perform this action"
54
+ )
55
+
56
+
48
57
router = APIRouter (prefix = "/organizations" , tags = ["organizations" ])
49
58
50
59
@@ -94,6 +103,49 @@ async def as_form(cls, id: int = Form(...), name: str = Form(...)):
94
103
95
104
# -- Routes --
96
105
106
+ def check_user_permission (
107
+ session : Session ,
108
+ user : User ,
109
+ org_id : int ,
110
+ permission : ValidPermissions
111
+ ) -> bool :
112
+ """
113
+ Check if user has the specified permission for the organization
114
+ """
115
+ # Get user's role in the organization
116
+ user_org = session .exec (
117
+ select (UserOrganizationLink ).where (
118
+ and_ (
119
+ UserOrganizationLink .user_id == user .id ,
120
+ UserOrganizationLink .organization_id == org_id
121
+ )
122
+ )
123
+ ).first ()
124
+
125
+ if not user_org :
126
+ return False
127
+
128
+ # Get permission ID
129
+ permission_record = session .exec (
130
+ select (Permission ).where (Permission .name == permission )
131
+ ).first ()
132
+
133
+ if not permission_record :
134
+ return False
135
+
136
+ # Check if role has the permission
137
+ role_permission = session .exec (
138
+ select (RolePermissionLink ).where (
139
+ and_ (
140
+ RolePermissionLink .role_id == user_org .role_id ,
141
+ RolePermissionLink .permission_id == permission_record .id
142
+ )
143
+ )
144
+ ).first ()
145
+
146
+ return bool (role_permission )
147
+
148
+
97
149
@router .post ("/" , response_class = RedirectResponse )
98
150
def create_organization (
99
151
org : OrganizationCreate = Depends (OrganizationCreate .as_form ),
@@ -110,11 +162,54 @@ def create_organization(
110
162
session .commit ()
111
163
session .refresh (db_org )
112
164
165
+ owner_role = session .exec (
166
+ select (Role ).where (
167
+ and_ (
168
+ Role .organization_id == db_org .id ,
169
+ Role .name == "Owner"
170
+ )
171
+ )
172
+ ).first ()
173
+
174
+ if not owner_role :
175
+ owner_role = Role (
176
+ name = "Owner" ,
177
+ organization_id = db_org .id
178
+ )
179
+ session .add (owner_role )
180
+ session .commit ()
181
+ session .refresh (owner_role )
182
+
183
+ user_org_link = UserOrganizationLink (
184
+ user_id = user .id ,
185
+ organization_id = db_org .id ,
186
+ role_id = owner_role .id
187
+ )
188
+ session .add (user_org_link )
189
+ session .commit ()
190
+
113
191
return RedirectResponse (url = f"/organizations/{ db_org .id } " , status_code = 303 )
114
192
115
193
116
194
@router .get ("/{org_id}" , response_model = OrganizationRead )
117
- def read_organization (org_id : int , user : User = Depends (get_authenticated_user ), session : Session = Depends (get_session )):
195
+ def read_organization (
196
+ org_id : int ,
197
+ user : User = Depends (get_authenticated_user ),
198
+ session : Session = Depends (get_session )
199
+ ):
200
+ # First check if user is a member of the organization
201
+ user_org = session .exec (
202
+ select (UserOrganizationLink ).where (
203
+ and_ (
204
+ UserOrganizationLink .user_id == user .id ,
205
+ UserOrganizationLink .organization_id == org_id
206
+ )
207
+ )
208
+ ).first ()
209
+
210
+ if not user_org :
211
+ raise InsufficientPermissionsError ()
212
+
118
213
db_org = session .get (Organization , org_id )
119
214
if not db_org :
120
215
raise OrganizationNotFoundError ()
@@ -127,6 +222,9 @@ def update_organization(
127
222
user : User = Depends (get_authenticated_user ),
128
223
session : Session = Depends (get_session )
129
224
) -> RedirectResponse :
225
+ if not check_user_permission (session , user , org .id , ValidPermissions .EDIT_ORGANIZATION ):
226
+ raise InsufficientPermissionsError ()
227
+
130
228
db_org = session .get (Organization , org .id )
131
229
if not db_org :
132
230
raise OrganizationNotFoundError ()
@@ -155,6 +253,9 @@ def delete_organization(
155
253
user : User = Depends (get_authenticated_user ),
156
254
session : Session = Depends (get_session )
157
255
) -> RedirectResponse :
256
+ if not check_user_permission (session , user , org_id , ValidPermissions .DELETE_ORGANIZATION ):
257
+ raise InsufficientPermissionsError ()
258
+
158
259
db_org = session .get (Organization , org_id )
159
260
if not db_org :
160
261
raise OrganizationNotFoundError ()
0 commit comments