def test_set_constrain_types(self): constraints = ISelectableConstrainTypes(self.belleville) self.assertListEqual(sorted(["Meeting", "Folder"]), sorted(constraints.getLocallyAllowedTypes())) utils.set_constrain_types(self.belleville, ["Meeting"]) self.assertListEqual(["Meeting"], constraints.getLocallyAllowedTypes()) utils.set_constrain_types(self.belleville, ["Meeting", "Folder"]) self.assertListEqual(["Folder", "Meeting"], constraints.getLocallyAllowedTypes())
def test_locallyAllowedTypesInvalidValuesGetFiltered(self): behavior = ISelectableConstrainTypes(self.folder) behavior.setConstrainTypesMode(constrains.ENABLED) self.folder.locally_allowed_types = self.types_id_subset + \ ['invalid'] self.assertEqual(self.types_id_subset, behavior.getLocallyAllowedTypes())
def test_foo_folder_constraintypes(self): foo = self.portal.get('foo') if IS_PLONE_5 or IS_PLONE_APP_MULTILINGUAL_2: constrains = ISelectableConstrainTypes(foo) self.assertEqual(constrains.getConstrainTypesMode(), constraintypes.ENABLED, 'Constraint types are not enabled on folder foo') self.assertItemsEqual(constrains.getImmediatelyAddableTypes(), ['Folder'], 'Immediately addable types are not configured well') self.assertItemsEqual(constrains.getLocallyAllowedTypes(), ['Folder', 'Document'], 'Locally addable types are not configured well') else: self.assertEqual(foo.getConstrainTypesMode(), constraintypes.ENABLED, 'Constraint types are not enabled on folder foo') self.assertEqual(foo.getImmediatelyAddableTypes(), ('Folder',), 'Immediately addable types are not configured well') self.assertEqual(foo.getLocallyAllowedTypes(), ('Folder', 'Document'), 'Locally addable types are not configured well')
def allowedContentTypes(self, context=None): """ If constraints are enabled, return the locally allowed types. If the setting is ACQUIRE, acquire the locally allowed types according to the ACQUIRE rules, described in the interface. If constraints are disabled, use the default addable types This method returns the FTI, NOT the FTI id, like most other methods. """ if context is None: context = self.context mode = self.getConstrainTypesMode() default_addable = self.getDefaultAddableTypes(context) if mode == DISABLED: return default_addable elif mode == ENABLED: if hasattr(self.context, 'locally_allowed_types'): return [t for t in default_addable if t.getId() in self.context.locally_allowed_types] else: return default_addable elif mode == ACQUIRE: parent = self.context.__parent__ parent_constrain_adapter = ISelectableConstrainTypes(parent, None) if not parent_constrain_adapter: return default_addable return_tids = self._filterByDefaults( parent_constrain_adapter.getLocallyAllowedTypes(context), context) return [t for t in default_addable if t.getId() in return_tids] else: raise Exception( "Wrong constraint setting. %i is an invalid value", mode)
def test_locallyAllowedTypesInvalidValuesGetFiltered(self): behavior = ISelectableConstrainTypes(self.folder) behavior.setConstrainTypesMode(constrains.ENABLED) self.folder.locally_allowed_types = self.types_id_subset + \ ['invalid'] self.assertEqual( self.types_id_subset, behavior.getLocallyAllowedTypes())
def allowedContentTypes(self, context=None): """ returns constrained allowed types as list of fti's. There is a try/except for handle AT folders inside DX containers """ if context is None: context = self mode = self.getConstrainTypesMode() # Short circuit if we are disabled or acquiring from non-compatible # parent parent = getParent(self) if mode == DISABLED or (mode == ACQUIRE and not parent): return PortalFolder.allowedContentTypes(self) elif mode == ACQUIRE and not parentPortalTypeEqual(self): globalTypes = self.getDefaultAddableTypes(context) if parent.portal_type == 'Plone Site': return globalTypes else: try: allowed = list(parent.getLocallyAllowedTypes(context)) except AttributeError: # parent is a DX content? behavior = ISelectableConstrainTypes(parent) if not behavior: # return context addable types return get_context_ftis(self) allowed = behavior.getLocallyAllowedTypes(context) return [fti for fti in globalTypes if fti.getId() in allowed] else: return get_context_ftis(self)
def allowedContentTypes(self, context=None): """ If constraints are enabled, return the locally allowed types. If the setting is ACQUIRE, acquire the locally allowed types according to the ACQUIRE rules, described in the interface. If constraints are disabled, use the default addable types This method returns the FTI, NOT the FTI id, like most other methods. """ if context is None: context = self.context mode = self.getConstrainTypesMode() default_addable = self.getDefaultAddableTypes(context) if mode == DISABLED: return default_addable elif mode == ENABLED: if hasattr(self.context, 'locally_allowed_types'): return [ t for t in default_addable if t.getId() in self.context.locally_allowed_types ] else: return default_addable elif mode == ACQUIRE: parent = self.context.__parent__ parent_constrain_adapter = ISelectableConstrainTypes(parent, None) if not parent_constrain_adapter: return default_addable return_tids = self._filterByDefaults( parent_constrain_adapter.getLocallyAllowedTypes(context), context) return [t for t in default_addable if t.getId() in return_tids] else: raise Exception("Wrong constraint setting. %i is an invalid value", mode)
def _showConstrainOptions(self): addContext = self._addContext() constrain = ISelectableConstrainTypes(addContext, None) if constrain is None: return False elif constrain.canSetConstrainTypes() and constrain.getDefaultAddableTypes(): return True elif len(constrain.getLocallyAllowedTypes()) < len(constrain.getImmediatelyAddableTypes()): return True
def export_constraints(self, item, obj): constrains = ISelectableConstrainTypes(obj, None) if constrains is None: return item if constrains.getConstrainTypesMode() == ENABLED: key = "exportimport.constrains" item[key] = { "locally_allowed_types": constrains.getLocallyAllowedTypes(), "immediately_addable_types": constrains.getImmediatelyAddableTypes(), } return item
def createRule(self, context, rule_context, rule_id, rule_title, rule_description, rule_event, message, subject, for_types=None, area_id=None): """ Enabled types are taken from the Plone registry, or you can manually set them using for_types Id of the area (used for getting the notification group) is taken from current area, or by area_id param """ registry = queryUtility(IRegistry) settings = registry.forInterface(IGroupwareNotifySettings, check=False) #create the rule rule = Rule() rule.__name__ = rule_id rule.event = rule_event rule.title = rule_title rule.description = rule_description #add the rule to rule's storage storage = getUtility(IRuleStorage) # chooser = INameChooser(storage) if rule_id not in storage.keys(): storage[rule_id] = rule #set the action and add it to the rule action = MailForGroupwareNotificationAction(area_id) if settings and settings.default_email_sender: action.source = settings.default_email_sender action.sender = None action.subject = subject action.message = message rule.actions.append(action) if not for_types: #set the condition and add it to the rule if settings: behavior = ISelectableConstrainTypes(rule_context) allowed_types = behavior.getLocallyAllowedTypes() types_list = set(allowed_types).difference(settings.black_list) condition = PortalTypeCondition() condition.check_types=tuple(types_list) rule.conditions.append(condition) else: # explicit types condition=PortalTypeCondition() condition.check_types=tuple(for_types) rule.conditions.append(condition) logger.info('Created rule %s' % rule_id) #assignment rule_id=rule.id.replace('++rule++','') assignable = IRuleAssignmentManager(rule_context) assignable[rule_id] = RuleAssignment(rule_id) assignable[rule_id].bubbles=True get_assignments(storage[rule_id]).insert('/'.join(rule_context.getPhysicalPath())) logger.info('Enabled rule %s on %s' % (rule_id, rule_context.Title().decode('utf-8')))
def test_form_save_restrictions(self): self.browser.open(self.folder_url) self.browser.getLink('Restrictions').click() ctrl = lambda name: self.browser.getControl(name=name) self.browser.getControl("Type restrictions").value = ['1'] ctrl("form.widgets.allowed_types:list").value = ["Document", "Folder"] ctrl("form.widgets.secondary_types:list").value = ["Document"] self.browser.getControl("Save").click() aspect = ISelectableConstrainTypes(self.folder) self.assertEqual(1, aspect.getConstrainTypesMode()) self.assertEqual(["Document", "Folder"], aspect.getLocallyAllowedTypes()) self.assertEqual(["Folder"], aspect.getImmediatelyAddableTypes())
def test_form_save_restrictions(self): self.browser.open(self.folder_url) self.browser.getLink('Restrictions').click() ctrl = lambda name: self.browser.getControl(name=name) self.browser.getControl("Type restrictions").value = ['1'] ctrl("form.widgets.allowed_types:list").value = ["Document", "Folder"] ctrl("form.widgets.secondary_types:list").value = ["Document"] self.browser.getControl("Save").click() aspect = ISelectableConstrainTypes(self.folder) self.assertEqual(1, aspect.getConstrainTypesMode()) self.assertEqual(["Document", "Folder"], aspect.getLocallyAllowedTypes()) self.assertEqual(["Folder"], aspect.getImmediatelyAddableTypes())
def allowedContentTypes(self, context=None): """ If constraints are enabled, return the locally allowed types. If the setting is ACQUIRE, acquire the locally allowed types according to the ACQUIRE rules, described in the interface. If constraints are disabled, use the default addable types This method returns the FTI, NOT the FTI id, like most other methods. """ portal = api.portal.getSite() subscribers = portal.portal_types.get('eea.meeting.subscribers') emails = portal.portal_types.get('eea.meeting.emails') if context is None: context = self.context mode = self.getConstrainTypesMode() default_addable = self.getDefaultAddableTypes(context) if mode == DISABLED: allowed = default_addable elif mode == ENABLED: if hasattr(self.context, 'locally_allowed_types'): allowed = [t for t in default_addable if t.getId() in self.context.locally_allowed_types] else: allowed = default_addable elif mode == ACQUIRE: parent = self.context.__parent__ parent_constrain_adapter = ISelectableConstrainTypes(parent, None) if not parent_constrain_adapter: allowed = default_addable else: return_tids = self._filterByDefaults( parent_constrain_adapter.getLocallyAllowedTypes(context)) allowed = [t for t in default_addable if t.getId() in return_tids] else: raise Exception( "Wrong constraint setting. %i is an invalid value", mode) if (IMeeting.providedBy(context) and context.get('subscribers')): if subscribers in allowed: allowed.remove(subscribers) if (IMeeting.providedBy(context) and context.get('emails')): if emails in allowed: allowed.remove(emails) return allowed
def test_allowedContentTypesExit3(self): """ Constrains are acquired, parent folder is of same type """ outer_behavior = ISelectableConstrainTypes(self.folder) assert len(outer_behavior.getLocallyAllowedTypes()) > 2 outer_behavior.setLocallyAllowedTypes(self.types_id_subset) outer_behavior.setConstrainTypesMode(constrains.ENABLED) behavior = ISelectableConstrainTypes(self.inner_folder) behavior.setConstrainTypesMode(constrains.ACQUIRE) self.assertEqual(self.types_id_subset, [x.getId() for x in behavior.allowedContentTypes()])
def test_locallyAllowedTypesDefaultWhenMultipleAcquired(self): """ Prevent regression. Multiple (two or more) acquisition from parent must not fail if user doesn't have add permission on parent. """ self.inner_folder.invokeFactory('folder', 'deeper_folder') deeper_folder = self.inner_folder.deeper_folder self.portal.acl_users._doAddUser('user_contributor', 'secret', ['Member'], []) deeper_folder.manage_addLocalRoles('user_contributor', ['Contributor']) login(self.portal, 'user_contributor') behavior = ISelectableConstrainTypes(deeper_folder) types = behavior.getLocallyAllowedTypes() self.assertTrue(len(types) > 0)
def test_allowedContentTypesExit3(self): """ Constrains are acquired, parent folder is of same type """ outer_behavior = ISelectableConstrainTypes(self.folder) assert len(outer_behavior.getLocallyAllowedTypes()) > 2 outer_behavior.setLocallyAllowedTypes(self.types_id_subset) outer_behavior.setConstrainTypesMode(constrains.ENABLED) behavior = ISelectableConstrainTypes(self.inner_folder) behavior.setConstrainTypesMode(constrains.ACQUIRE) self.assertEquals(self.types_id_subset, [x.getId() for x in behavior.allowedContentTypes()])
def test_locallyAllowedTypesDefaultWhenMultipleAcquired(self): """ Prevent regression. Multiple (two or more) acquisition from parent must not fail if user doesn't have add permission on parent. """ self.inner_folder.invokeFactory('folder', 'deeper_folder') deeper_folder = self.inner_folder.deeper_folder self.portal.acl_users._doAddUser('user_contributor', 'secret', ['Member'], []) deeper_folder.manage_addLocalRoles('user_contributor', ['Contributor']) login(self.portal, 'user_contributor') behavior = ISelectableConstrainTypes(deeper_folder) types = behavior.getLocallyAllowedTypes() self.assertTrue(len(types) > 0)
def test_locallyAllowedTypesDefaultWhenAcquired(self): """ Constrain Mode set to ACQUIRE Try to acquire the constrains, if that fails, use the defaults """ behavior = ISelectableConstrainTypes(self.inner_folder) behavior.setConstrainTypesMode(constrains.ACQUIRE) behavior.setLocallyAllowedTypes([]) outer_behavior = ISelectableConstrainTypes(self.folder) outer_behavior.setConstrainTypesMode(constrains.ENABLED) outer_behavior.setLocallyAllowedTypes(self.types_id_subset) types = self.types_id_subset self.assertEqual(types, behavior.getLocallyAllowedTypes()) outer_behavior.setConstrainTypesMode(constrains.ACQUIRE) types = self.default_types type_ids = [t.getId() for t in types] self.assertEqual(types, behavior.allowedContentTypes()) self.assertEqual(type_ids, behavior.getLocallyAllowedTypes())
def test_locallyAllowedTypesDefaultWhenAcquired(self): """ Constrain Mode set to ACQUIRE Try to acquire the constrains, if that fails, use the defaults """ behavior = ISelectableConstrainTypes(self.inner_folder) behavior.setConstrainTypesMode(constrains.ACQUIRE) behavior.setLocallyAllowedTypes([]) outer_behavior = ISelectableConstrainTypes(self.folder) outer_behavior.setConstrainTypesMode(constrains.ENABLED) outer_behavior.setLocallyAllowedTypes(self.types_id_subset) types = self.types_id_subset self.assertEqual(types, behavior.getLocallyAllowedTypes()) outer_behavior.setConstrainTypesMode(constrains.ACQUIRE) types = self.default_types type_ids = [t.getId() for t in types] self.assertEqual(types, behavior.allowedContentTypes()) self.assertEqual(type_ids, behavior.getLocallyAllowedTypes())
def test_form_save_restrictions(self): self.browser.open(self.folder_url) self.browser.getLink('Restrictions').click() def ctrl(name): return self.browser.getControl(name=name) self.browser.getControl('Type restrictions').value = ['1'] ctrl('form.widgets.allowed_types:list').value = ['Document', 'Folder'] ctrl('form.widgets.secondary_types:list').value = ['Document'] self.browser.getControl('Save').click() aspect = ISelectableConstrainTypes(self.folder) self.assertEqual(1, aspect.getConstrainTypesMode()) self.assertEqual(['Document', 'Folder'], aspect.getLocallyAllowedTypes()) self.assertEqual(['Folder'], aspect.getImmediatelyAddableTypes())
def test_form_save_restrictions(self): self.browser.open(self.folder_url) self.browser.getLink('Restrictions').click() def ctrl(name): return self.browser.getControl(name=name) self.browser.getControl('Type restrictions').value = ['1'] ctrl('form.widgets.allowed_types:list').value = ['Document', 'Folder'] ctrl('form.widgets.secondary_types:list').value = ['Document'] self.browser.getControl('Save').click() aspect = ISelectableConstrainTypes(self.folder) self.assertEqual(1, aspect.getConstrainTypesMode()) self.assertEqual( ['Document', 'Folder'], aspect.getLocallyAllowedTypes() ) self.assertEqual(['Folder'], aspect.getImmediatelyAddableTypes())
def test_locallyAllowedTypesDefaultWhenDisabled(self): """ Constrain Mode Disabled. We get the default constrains, independent of what our parent folder or we ourselves defined """ behavior = ISelectableConstrainTypes(self.inner_folder) behavior.setConstrainTypesMode(constrains.DISABLED) behavior.setLocallyAllowedTypes([]) outer_behavior = ISelectableConstrainTypes(self.folder) outer_behavior.setConstrainTypesMode(constrains.ENABLED) outer_behavior.setLocallyAllowedTypes([]) types = self.default_types type_ids = [t.getId() for t in types] self.assertEqual(types, behavior.allowedContentTypes()) self.assertEqual(type_ids, behavior.getLocallyAllowedTypes())
def test_locallyAllowedTypesDefaultWhenDisabled(self): """ Constrain Mode Disabled. We get the default constrains, independent of what our parent folder or we ourselves defined """ behavior = ISelectableConstrainTypes(self.inner_folder) behavior.setConstrainTypesMode(constrains.DISABLED) behavior.setLocallyAllowedTypes([]) outer_behavior = ISelectableConstrainTypes(self.folder) outer_behavior.setConstrainTypesMode(constrains.ENABLED) outer_behavior.setLocallyAllowedTypes([]) types = self.default_types type_ids = [t.getId() for t in types] self.assertEqual(types, behavior.allowedContentTypes()) self.assertEqual(type_ids, behavior.getLocallyAllowedTypes())
def _updateFolder(obj, types=None, view=None, authenticated_roles=None): if view is not None: obj.setLayout(view) if types is not None: aspect = ISelectableConstrainTypes(obj) addable = aspect.getLocallyAllowedTypes() if types != addable: aspect.setConstrainTypesMode(1) # Need to be globally allowed in order to be set as locally allowed # or to create a custom folderish content type with # "allowed_content_types" # Only a blacklist, not a whitelist setattr(obj, 'locally_allowed_types', types) setattr(obj, 'immediately_addable_types', types) if authenticated_roles is not None: obj.manage_setLocalRoles('AuthenticatedUsers', authenticated_roles) # Move view permission from Anonymous to Member obj.manage_permission(View, acquire=False, roles=('Authenticated', 'Member', 'Manager', 'Site Administrator'))
def test_locallyAllowedTypesDefaultWhenEnabled(self): """ Constrain Mode enabled We get the set constrains, independent of what our parent folder defined """ behavior = ISelectableConstrainTypes(self.inner_folder) behavior.setConstrainTypesMode(constrains.ENABLED) behavior.setLocallyAllowedTypes(self.types_id_subset) outer_behavior = ISelectableConstrainTypes(self.folder) outer_behavior.setConstrainTypesMode(constrains.ENABLED) outer_behavior.setLocallyAllowedTypes([]) types = [t for t in self.default_types if t.getId() in self.types_id_subset] type_ids = self.types_id_subset self.assertEqual(types, behavior.allowedContentTypes()) self.assertEqual(type_ids, behavior.getLocallyAllowedTypes())
def test_locallyAllowedTypesDefaultWhenEnabled(self): """ Constrain Mode enabled We get the set constrains, independent of what our parent folder defined """ behavior = ISelectableConstrainTypes(self.inner_folder) behavior.setConstrainTypesMode(constrains.ENABLED) behavior.setLocallyAllowedTypes(self.types_id_subset) outer_behavior = ISelectableConstrainTypes(self.folder) outer_behavior.setConstrainTypesMode(constrains.ENABLED) outer_behavior.setLocallyAllowedTypes([]) types = [ t for t in self.default_types if t.getId() in self.types_id_subset ] type_ids = self.types_id_subset self.assertEqual(types, behavior.allowedContentTypes()) self.assertEqual(type_ids, behavior.getLocallyAllowedTypes())
def getLocallyAllowedTypes(self, context=None): """ There is a try/except for handle AT folders inside DX containers """ if context is None: context = self mode = self.getConstrainTypesMode() if mode == DISABLED: return [fti.getId() for fti in self.getDefaultAddableTypes(context)] elif mode == ENABLED: return self.getField('locallyAllowedTypes').get(self) elif mode == ACQUIRE: parent = getParent(self) if not parent or parent.portal_type == 'Plone Site': return [fti.getId() for fti in self.getDefaultAddableTypes(context)] elif not parentPortalTypeEqual(self): # if parent.portal_type != self.portal_type: default_addable_types = [fti.getId() for fti in self.getDefaultAddableTypes(context)] try: locally_allowed_types = parent.getLocallyAllowedTypes(context) if ISelectableConstrainTypes.providedBy(parent) else parent.getLocallyAllowedTypes() except AttributeError: # parent is a DX content? behavior = ISelectableConstrainTypes(parent) if not behavior: # return context default addable types return default_addable_types locally_allowed_types = behavior.getLocallyAllowedTypes(context) if ISelectableConstrainTypes.providedBy(parent) else behavior.getLocallyAllowedTypes() return [t for t in locally_allowed_types if t in default_addable_types] else: if ISelectableConstrainTypes.providedBy(parent): return parent.getLocallyAllowedTypes(context) else: return parent.getLocallyAllowedTypes() else: raise ValueError, "Invalid value for enableAddRestriction"