Updated permission check in container delete helper function
authorThierry Florac <thierry.florac@onf.fr>
Wed, 11 Apr 2018 10:55:37 +0200
changeset 309 820cffe32002
parent 308 c034ad3fb601
child 310 bb06ce0733ac
Updated permission check in container delete helper function
src/pyams_skin/container.py
--- a/src/pyams_skin/container.py	Tue Apr 10 15:32:01 2018 +0200
+++ b/src/pyams_skin/container.py	Wed Apr 11 10:55:37 2018 +0200
@@ -18,13 +18,14 @@
 # import interfaces
 from pyams_skin.interfaces.container import IContainerBaseView
 from pyams_skin.layer import IPyAMSLayer
-from pyams_utils.interfaces import MANAGE_PERMISSION
 from zope.container.interfaces import IContainer
 
 # import packages
+from pyams_form.security import get_edit_permission
 from pyams_skin.table import BaseTable
 from pyams_template.template import template_config
 from pyramid.exceptions import NotFound
+from pyramid.httpexceptions import HTTPUnauthorized, HTTPInternalServerError
 from pyramid.view import view_config
 from zope.interface import implementer
 
@@ -48,10 +49,19 @@
 
 
 @view_config(name='delete-element.json', context=IContainer, request_type=IPyAMSLayer,
-             permission=MANAGE_PERMISSION, renderer='json', xhr=True)
-def delete_container_element(request):
-    """Delete container element"""
+             renderer='json', xhr=True)
+def delete_container_element(request, container_factory=None, ignore_permission=False):
+    """Delete container element
+
+    This view is not strictly protected, but:
+    - either the function is called from another protected view
+    - either the view is checking edit permission from context adapter; if permission can't be found,
+      an internal server error is raised!
+    If the function is called from another unprotected view with 'ignore_permission=True',
+    it's a configuration error.
+    """
     translate = request.localizer.translate
+    # Get object name to be removed
     name = request.params.get('object_name')
     if not name:
         return {
@@ -61,15 +71,29 @@
                 'content': translate(_("No provided object_name argument!"))
             }
         }
-    if name not in request.context:
+    # Check container factory
+    container = request.context
+    if container_factory is not None:
+        container = container_factory(container)
+    # Check container
+    if name not in container:
         return {
             'status': 'message',
             'messagebox': {
                 'status': 'error',
-                'content': translate(_("Given plug-in name doesn't exist!"))
+                'content': translate(_("Given element name doesn't exist!"))
             }
         }
-    del request.context[name]
+    # Check permission
+    if not ignore_permission:
+        context = container[name]
+        permission = get_edit_permission(request, context)
+        if permission is None:
+            raise HTTPInternalServerError("Missing permission definition")
+        elif not request.has_permission(permission, context):
+            raise HTTPUnauthorized()
+    # Delete element
+    del container[name]
     return {'status': 'success'}