From fe3a1740d6b0490b8db9d5dc3364d353c7e22fa8 Mon Sep 17 00:00:00 2001 From: Kazuhiko Shiozaki <kazuhiko@nexedi.com> Date: Wed, 16 Dec 2015 10:11:32 +0100 Subject: [PATCH] monkey patch ExternalMethod so that we have Guard like DCWorkflow.Transition. --- product/ERP5Type/patches/ExternalMethod.py | 28 ++++++++++++++++++++++ product/ERP5Type/patches/PythonScript.py | 10 ++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/product/ERP5Type/patches/ExternalMethod.py b/product/ERP5Type/patches/ExternalMethod.py index 7044bdf993..bf18a97736 100644 --- a/product/ERP5Type/patches/ExternalMethod.py +++ b/product/ERP5Type/patches/ExternalMethod.py @@ -13,6 +13,13 @@ from inspect import getargs from Products.ExternalMethod.ExternalMethod import * +from AccessControl import ModuleSecurityInfo +from AccessControl.class_init import InitializeClass +from Acquisition import aq_parent +from Products.ERP5Type.patches.PythonScript import _guard_form, \ + _guard_manage_options, checkGuard, getGuard, manage_guardForm, \ + manage_setGuard +from zExceptions import Forbidden if 1: def getFunction(self, reload=False, f=None): @@ -74,6 +81,7 @@ if 1: first argument. Monkey patches: + - check guard against context, if guard exists. - call ZODB Component Extension, by trying first to import ZODB Component Extension if available, otherwise fallback on filesystem Extension @@ -81,6 +89,11 @@ if 1: - fix magic "self" argument when positional arguments get their values from kw. """ + guard = getattr(self, 'guard', None) + if guard is not None: + if not checkGuard(guard, aq_parent(self)): + raise Forbidden, 'Calling %s %s is denied by Guard.' % (self.meta_type, self.id) + import erp5.component.extension component_module = erp5.component.extension.find_load_module(self._module) if component_module is not None: @@ -133,3 +146,18 @@ if 1: finally: tb=None ExternalMethod.__call__ = __call__ + +security = ModuleSecurityInfo('Products.ExternalMethod.ExternalMethod.ExternalMethod') + +ExternalMethod.manage_options += _guard_manage_options +ExternalMethod._guard_form = _guard_form + +ExternalMethod.manage_guardForm = manage_guardForm +security.declareProtected(view_management_screens, 'manage_guardForm') + +ExternalMethod.getGuard = getGuard + +ExternalMethod.manage_setGuard = manage_setGuard +security.declareProtected(change_external_methods, 'manage_setGuard') + +InitializeClass(ExternalMethod) diff --git a/product/ERP5Type/patches/PythonScript.py b/product/ERP5Type/patches/PythonScript.py index a190fe5316..a93ea8e506 100644 --- a/product/ERP5Type/patches/PythonScript.py +++ b/product/ERP5Type/patches/PythonScript.py @@ -16,6 +16,7 @@ from Products.PythonScripts.PythonScript import PythonScript from App.special_dtml import DTMLFile from Products.ERP5Type import _dtmldir from AccessControl import ModuleSecurityInfo, getSecurityManager +from AccessControl.class_init import InitializeClass from OFS.misc_ import p_ from App.ImageFile import ImageFile from Acquisition import aq_base, aq_parent @@ -58,14 +59,17 @@ PythonScript.manage_editForm = manage_editForm security = ModuleSecurityInfo('Products.PythonScripts.PythonScript.PythonScript') -PythonScript.manage_options += ( +_guard_manage_options = ( { 'label':'Guard', 'action':'manage_guardForm', }, ) -PythonScript._guard_form = DTMLFile( +PythonScript.manage_options += _guard_manage_options + +_guard_form = DTMLFile( 'editGuardForm', _dtmldir) +PythonScript._guard_form = _guard_form def manage_guardForm(self, REQUEST, manage_tabs_message=None): ''' @@ -157,3 +161,5 @@ def _exec(self, *args): # PATCH END return PythonScript_exec(self, *args) PythonScript._exec = _exec + +InitializeClass(PythonScript) -- 2.30.9