44from mavedb .lib .logging .context import save_to_logging_context
55from mavedb .lib .permissions .actions import Action
66from mavedb .lib .permissions .models import PermissionResponse
7- from mavedb .lib .permissions .utils import roles_permitted
7+ from mavedb .lib .permissions .utils import deny_action_for_entity , roles_permitted
88from mavedb .models .collection import Collection
99from mavedb .models .enums .contribution_role import ContributionRole
1010from mavedb .models .enums .user_role import UserRole
@@ -20,8 +20,8 @@ def has_permission(user_data: Optional[UserData], entity: Collection, action: Ac
2020
2121 Args:
2222 user_data: The user's authentication data and roles. None for anonymous users.
23- action: The action to be performed (READ, UPDATE, DELETE, ADD_EXPERIMENT_SET).
2423 entity: The Collection entity to check permissions for.
24+ action: The action to be performed (READ, UPDATE, DELETE, ADD_EXPERIMENT, ADD_SCORE_SET, ADD_ROLE, ADD_BADGE).
2525
2626 Returns:
2727 PermissionResponse: Contains permission result, HTTP status code, and message.
@@ -107,6 +107,7 @@ def _handle_read_action(
107107 user_data: The user's authentication data.
108108 entity: The Collection entity being accessed.
109109 private: Whether the Collection is private.
110+ official_collection: Whether the Collection is an official collection.
110111 user_is_owner: Whether the user owns the Collection.
111112 collection_roles: The user's roles in this Collection (admin/editor/viewer).
112113 active_roles: List of the user's active roles.
@@ -128,7 +129,7 @@ def _handle_read_action(
128129 if roles_permitted (active_roles , [UserRole .admin ]):
129130 return PermissionResponse (True )
130131
131- return _deny_action_for_collection (entity , private , user_data , bool (collection_roles ) or user_is_owner )
132+ return deny_action_for_entity (entity , private , user_data , bool (collection_roles ) or user_is_owner )
132133
133134
134135def _handle_update_action (
@@ -149,6 +150,7 @@ def _handle_update_action(
149150 user_data: The user's authentication data.
150151 entity: The Collection entity being updated.
151152 private: Whether the Collection is private.
153+ official_collection: Whether the Collection is an official collection.
152154 user_is_owner: Whether the user owns the Collection.
153155 collection_roles: The user's roles in this Collection (admin/editor/viewer).
154156 active_roles: List of the user's active roles.
@@ -167,7 +169,7 @@ def _handle_update_action(
167169 if roles_permitted (active_roles , [UserRole .admin ]):
168170 return PermissionResponse (True )
169171
170- return _deny_action_for_collection (entity , private , user_data , bool (collection_roles ) or user_is_owner )
172+ return deny_action_for_entity (entity , private , user_data , bool (collection_roles ) or user_is_owner )
171173
172174
173175def _handle_delete_action (
@@ -189,6 +191,7 @@ def _handle_delete_action(
189191 user_data: The user's authentication data.
190192 entity: The Collection entity being deleted.
191193 private: Whether the Collection is private.
194+ official_collection: Whether the Collection is official.
192195 user_is_owner: Whether the user owns the Collection.
193196 collection_roles: The user's roles in this Collection (admin/editor/viewer).
194197 active_roles: List of the user's active roles.
@@ -202,16 +205,12 @@ def _handle_delete_action(
202205 return PermissionResponse (True )
203206 # Other users may only delete non-official collections.
204207 if not official_collection :
205- # Owners may delete a collection only if it has not been published .
208+ # Owners may delete a collection only if it is still private .
206209 # Collection admins/editors/viewers may not delete collections.
207- if user_is_owner :
208- return PermissionResponse (
209- private ,
210- 403 ,
211- f"insufficient permissions for URN '{ entity .urn } '" ,
212- )
210+ if user_is_owner and private :
211+ return PermissionResponse (True )
213212
214- return _deny_action_for_collection (entity , private , user_data , bool (collection_roles ) or user_is_owner )
213+ return deny_action_for_entity (entity , private , user_data , bool (collection_roles ) or user_is_owner )
215214
216215
217216def _handle_publish_action (
@@ -232,6 +231,7 @@ def _handle_publish_action(
232231 user_data: The user's authentication data.
233232 entity: The Collection entity being published.
234233 private: Whether the Collection is private.
234+ official_collection: Whether the Collection is official.
235235 user_is_owner: Whether the user owns the Collection.
236236 collection_roles: The user's roles in this Collection (admin/editor/viewer).
237237 active_roles: List of the user's active roles.
@@ -249,7 +249,7 @@ def _handle_publish_action(
249249 if roles_permitted (active_roles , [UserRole .admin ]):
250250 return PermissionResponse (True )
251251
252- return _deny_action_for_collection (entity , private , user_data , bool (collection_roles ) or user_is_owner )
252+ return deny_action_for_entity (entity , private , user_data , bool (collection_roles ) or user_is_owner )
253253
254254
255255def _handle_add_experiment_action (
@@ -290,7 +290,7 @@ def _handle_add_experiment_action(
290290 if roles_permitted (active_roles , [UserRole .admin ]):
291291 return PermissionResponse (True )
292292
293- return _deny_action_for_collection (entity , private , user_data , bool (collection_roles ) or user_is_owner )
293+ return deny_action_for_entity (entity , private , user_data , bool (collection_roles ) or user_is_owner )
294294
295295
296296def _handle_add_score_set_action (
@@ -330,7 +330,7 @@ def _handle_add_score_set_action(
330330 if roles_permitted (active_roles , [UserRole .admin ]):
331331 return PermissionResponse (True )
332332
333- return _deny_action_for_collection (entity , private , user_data , bool (collection_roles ) or user_is_owner )
333+ return deny_action_for_entity (entity , private , user_data , bool (collection_roles ) or user_is_owner )
334334
335335
336336def _handle_add_role_action (
@@ -369,7 +369,7 @@ def _handle_add_role_action(
369369 if roles_permitted (active_roles , [UserRole .admin ]):
370370 return PermissionResponse (True )
371371
372- return _deny_action_for_collection (entity , private , user_data , bool (collection_roles ) or user_is_owner )
372+ return deny_action_for_entity (entity , private , user_data , bool (collection_roles ) or user_is_owner )
373373
374374
375375def _handle_add_badge_action (
@@ -402,40 +402,4 @@ def _handle_add_badge_action(
402402 if roles_permitted (active_roles , [UserRole .admin ]):
403403 return PermissionResponse (True )
404404
405- return _deny_action_for_collection (entity , private , user_data , bool (collection_roles ) or user_is_owner )
406-
407-
408- def _deny_action_for_collection (
409- entity : Collection ,
410- private : bool ,
411- user_data : Optional [UserData ],
412- user_may_view_private : bool = False ,
413- ) -> PermissionResponse :
414- """
415- Generate appropriate denial response for Collection permission checks.
416-
417- This helper function determines the correct HTTP status code and message
418- when denying access to a Collection based on its privacy and user authentication.
419-
420- Args:
421- entity: The Collection entity being accessed.
422- private: Whether the Collection is private.
423- user_data: The user's authentication data (None for anonymous).
424- user_may_view_private: Whether the user has any role allowing them to view private collections.
425-
426- Returns:
427- PermissionResponse: Denial response with appropriate HTTP status and message.
428-
429- Note:
430- Returns 404 for private entities to avoid information disclosure,
431- 401 for unauthenticated users, and 403 for insufficient permissions.
432- """
433- # Do not acknowledge the existence of a private collection.
434- if private and not user_may_view_private :
435- return PermissionResponse (False , 404 , f"collection with URN '{ entity .urn } ' not found" )
436- # No authenticated user is present.
437- if user_data is None or user_data .user is None :
438- return PermissionResponse (False , 401 , f"insufficient permissions for URN '{ entity .urn } '" )
439-
440- # The authenticated user lacks sufficient permissions.
441- return PermissionResponse (False , 403 , f"insufficient permissions for URN '{ entity .urn } '" )
405+ return deny_action_for_entity (entity , private , user_data , bool (collection_roles ) or user_is_owner )
0 commit comments