from cgi import escape from AccessControl.SecurityInfo import ClassSecurityInfo from Acquisition import Explicit from Acquisition import aq_base from App.class_init import InitializeClass from App.special_dtml import DTMLFile from Persistence import Persistent from Products.CMFCore.Expression import Expression from Products.CMFCore.utils import _checkPermission from Products.DCWorkflow.Expression import StateChangeInfo from Products.DCWorkflow.Expression import createExprContext from Products.DCWorkflow.permissions import ManagePortal from Products.DCWorkflow.utils import _dtmldir # XXX(WORKFLOW) remove dependencies to DCWorkflow ^ class GuardableMixin(object): ''' code of methods and functions taken from Products.DCWorkflow-2.2.4 > Guard.py ''' guard_expression = Expression('') guard_group = () guard_permission = () guard_role = () security = ClassSecurityInfo() security.declareObjectProtected(ManagePortal) def checkGuard(self, security_manager, workflow, current_object, check_roles=True, **kw): """Checks conditions in this guard. """ user_roles = None if workflow.manager_bypass: # Possibly bypass. user_roles = security_manager.getUser().getRolesInContext(current_object) if 'Manager' in user_roles: return True if self.guard_permission: for permission in self.guard_permission: if _checkPermission(permission, current_object): break else: return False if check_roles and self.guard_role: # Require at least one of the given roles. if user_roles is None: user_roles = security_manager.getUser()\ .getRolesInContext(current_object) for role in self.guard_role: if role in user_roles: break else: return False if self.guard_group: # Require at least one of the specified groups. user = security_manager.getUser() base = aq_base(user) if hasattr(base, 'getGroupsInContext'): user_groups = user.getGroupsInContext(current_object) elif hasattr(base, 'getGroups' ): user_groups = user.getGroups() else: user_groups = () for group in self.guard_group: if group in user_groups: break else: return False if self.guard_expression and self.guard_expression.text: expression_context = createExprContext(StateChangeInfo(current_object, workflow, kwargs=kw)) if not self.guard_expression(expression_context): return False return True security.declareProtected(ManagePortal, 'getSummary') def getSummary(self): # Perhaps ought to be in DTML. summary = [] if self.guard_permission: summary.append('Requires permission:') summary.append(formatNameUnion(self.guard_permission)) if self.guard_role: if summary: summary.append('<br/>') summary.append('Requires role:') summary.append(formatNameUnion(self.guard_role)) if self.guard_group: if summary: summary.append('<br/>') summary.append('Requires group:') summary.append(formatNameUnion(self.guard_group)) if self.guard_expression is not None: if summary: summary.append('<br/>') summary.append('Requires expr:') summary.append('<code>' + escape(self.guard_expression.text) + '</code>') return ' '.join(summary) def changeFromProperties(self, props): ''' Returns True if changes were specified. ''' if props is None: return False changed = False given_property = props.get('guard_permission', None) if given_property: changed = True permission_list = [permission.strip() for permission in given_property.split(';')] self.guard_permission = tuple(permission_list) given_property = props.get('guard_role', None) if given_property: changed = True role_list = [role.strip() for role in given_property.split(';')] self.guard_role = tuple(role_list) given_property = props.get('guard_group', None) if given_property: changed = True group_list = [ group.strip() for group in given_property.split(';') ] self.guard_group = tuple(group_list) given_property = props.get('guard_expression', None) if given_property: changed = True self.guard_expression = Expression(given_property) return changed security.declareProtected(ManagePortal, 'setGuardExpression') def setGuardExpression(self, text): self.guard_expression = Expression(text) security.declareProtected(ManagePortal, 'getGuardExpression') def getGuardExpression(self): if self.guard_expression is None: return Expression('') return self.guard_expression def formatNameUnion(names): escaped = ['<code>' + escape(name) + '</code>' for name in names] if len(escaped) == 2: return ' or '.join(escaped) elif len(escaped) > 2: escaped[-1] = ' or ' + escaped[-1] return '; '.join(escaped)