Beispiel #1
0
def _updatePluginRegistry(registry, xml, should_purge, encoding=None):

    if should_purge:
        registry._plugin_types = []
        registry._plugin_type_info = PersistentMapping()
        registry._plugins = PersistentMapping()

    # When PAS import is used in an extension profile, the plugin
    # registry will have been deleted (content import deletes by
    # default) but should_purge will be false; need to initialize
    # _plugins since PluginRegistry's constructor doesn't
    if registry._plugins is None:
        registry._plugins = PersistentMapping()

    pir = PluginRegistryImporter(registry, encoding)
    reg_info = pir.parseXML(xml)

    for info in reg_info['plugin_types']:
        iface = _resolveDottedName(info['interface'])
        # Avoid duplicate plugin types
        if iface not in registry._plugin_types:
            registry._plugin_types.append(iface)
        registry._plugin_type_info[iface] = {
            'id': info['id'],
            'title': info['title'],
            'description': info['description'],
        }
        registry._plugins[iface] = tuple([x['id'] for x in info['plugins']])
    def allCriteria(self, bib_type=None):

        # migrate CMFBAT v0.8 duplicates engine, mending a linguistic fault-pas
        if shasattr(self, '_criterias'):
            print 'CMFBibliographyAT: performing duplicates engine property update - v0.8 -> v0.9 (allCriteria of %s)' % '/'.join(self.getId())
            self._criteria = PersistentMapping()
            self.initCriteria()
            try: delattr(self, '_criterias')
            except: pass

        # this should have been performed by __init__ but after some product migrations we might want to check it here again
        if not shasattr(self, '_criteria'):
            self._criteria = PersistentMapping()
        if not shasattr(self, 'duplicates_criteria'):
            self.duplicates_criteria = PersistentMapping()

        # first call? initialize self._criteria (available duplicates criteria per reference type)
        if not self._criteria:
            self.initCriteria()

        # always init criteria, during development, schema changes, etc.
        self.initCriteria()
        if bib_type:
            try:
                self._criteria[bib_type]
            except KeyError:
                return False

            return self._criteria[bib_type]
        else:
            critKeys = self._criteria.keys()
            critKeys.sort()
            return [(key, self._criteria[key]) for key in critKeys]
 def initCriteria(self):
     """ initialize the dictionary of import criteria
     for each bibliography type
     """
     # this is a migration 0.8 -> 0.9 fix:
     if not shasattr(self, '_criteria'):
         self._criteria = PersistentMapping()
     bib_tool = getToolByName(self, 'portal_bibliography')
     has = self._criteria_names.has_key
     for bib_type in bib_tool.getBibliographyContentTypes():
         bibname = bib_type['name']
         self._criteria[bibname] = [
             criteria for criteria in self._nonmeta_criteria
         ]
         #adds all meta_data as criteria for each bibliography type
         for field in bib_type['schema'].fields():
             field_name = field.getName()
             if field_name in self._ignored_criteria:
                 continue
             if not shasattr(field, 'is_duplicates_criterion'):
                 continue
             if not field.is_duplicates_criterion:
                 continue
             if has(field_name):
                 self._criteria[bibname].append(
                     self._criteria_names[field_name])
             else:
                 self._criteria[bibname].append(field_name)
         self._criteria[bibname].sort()
         self._criteria[bibname] = tuple(self._criteria[bibname])
Beispiel #4
0
    def get_po_header(self, lang):
        """ """
        # For backwards compatibility
        if not hasattr(aq_base(self), '_po_headers'):
            self._po_headers = PersistentMapping()

        return self._po_headers.get(lang, empty_po_header)
Beispiel #5
0
def _initDCWorkflowStates(workflow, states):
    """ Initialize DCWorkflow states
    """
    from Products.DCWorkflow.States import StateDefinition

    for s_info in states:

        id = str(s_info['state_id'])  # no unicode!
        if not workflow.states.has_key(id):
            s = StateDefinition(id)
            workflow.states._setObject(id, s)
        s = workflow.states._getOb(id)

        s.setProperties(title=s_info['title'],
                        description=s_info['description'],
                        transitions=s_info['transitions'])

        for k, v in s_info['permissions'].items():
            s.setPermission(k, isinstance(v, list), v)

        gmap = s.group_roles = PersistentMapping()

        for group_id, roles in s_info['groups']:
            gmap[group_id] = roles

        vmap = s.var_values = PersistentMapping()

        for name, v_info in s_info['variables'].items():

            value = _convertVariableValue(v_info['value'], v_info['type'])

            vmap[name] = value
Beispiel #6
0
 def setPermission(self, permission, roles, REQUEST=None):
     """
 Set a permission for this State.
 """
     if self.state_permission_role_list_dict is None:
         self.state_permission_role_list_dict = PersistentMapping()
     self.state_permission_role_list_dict[permission] = tuple(roles)
Beispiel #7
0
 def getTreeIdList(self, htree=None):
     """ Return list of all tree ids
     """
     if self._tree_list is None or len(self._tree_list.keys()) == 0:
         tree_list = self._getTreeIdList(htree=htree)
         self._tree_list = PersistentMapping()
         for tree in tree_list:                
             self._tree_list[tree] = None
     return sorted(self._tree_list.keys())
 def setCriteria(self, duplicates_criteria):
     """update criteria for all bibliography types"""
     if not duplicates_criteria:
         duplicates_criteria = {}
         bib_tool = getToolByName(self, 'portal_bibliography')
         for key in bib_tool.getReferenceTypes():
             duplicates_criteria[key] = []
     self.duplicates_criteria = PersistentMapping(duplicates_criteria)
     self.criteriaUpdated = True
Beispiel #9
0
    def listPolicies(self):
        """ return the list of defined policies

        a policy is a 2-uple (output_mime_type, [list of required transforms])
        """
        # XXXFIXME: backward compat, should be removed latter
        if not hasattr(self, '_policies'):
            self._policies = PersistentMapping()
        return self._policies.items()
 def __init__(self):
     self._schemas = PersistentMapping()
     self._templates = PersistentMapping()
     self._registeredTemplates = PersistentMapping()
     # meta_type -> [names of CatalogTools]
     self.catalog_map = PersistentMapping()
     self.catalog_map['Reference'] = []  # References not in portal_catalog
     # DM (avoid persistency bug): "_types" now maps known schemas to signatures
     self._types = {}
Beispiel #11
0
 def setStatePermissionRoleListDict(self, permission_roles):
     """
 create a dict containing the state's permission (as key) and its
 associated role list (value)
 use a PersistentMapping so that the ZODB is updated
 when this dict is changed
 """
     self.state_permission_role_list_dict = PersistentMapping(
         {k: tuple(v)
          for (k, v) in permission_roles.items()})
Beispiel #12
0
    def __init__(self, plugin_type_info):

        self._plugin_types = [x[0] for x in plugin_type_info]
        self._plugin_type_info = PersistentMapping()
        for interface in plugin_type_info:
            self._plugin_type_info[interface[0]] = {
                'id': interface[1],
                'title': interface[2],
                'description': interface[3]
            }
Beispiel #13
0
def setDependentProducts(jar, productid, dep_ids):
    productid = str(productid)
    rd = _getCentralRefreshData(jar, 1)
    products = rd.get('products', None)
    if products is None:
        rd['products'] = products = PersistentMapping()
    product = products.get(productid, None)
    if product is None:
        products[productid] = product = PersistentMapping()
    product['dependent_products'] = tuple(map(str, dep_ids))
 def _save_user_state(self, user_name, user_state):
     """ Saves the state for the passed user to the session database """
     if user_state:
         user_state_json = json.dumps(user_state)
         user_settings = getattr(self._dmd.ZenUsers, user_name)
         state_container = getattr(user_settings, '_browser_state', None)
         if isinstance(state_container, basestring) or state_container is None:
             state_container = PersistentMapping()
             user_settings._browser_state = state_container
         if user_state_json != state_container.get('state', ''):
             state_container['state'] = user_state_json
Beispiel #15
0
    def _getPlugins(self, plugin_type):

        parent = aq_parent(aq_inner(self))

        if plugin_type not in self._plugin_types:
            raise KeyError, plugin_type

        if self._plugins is None:
            self._plugins = PersistentMapping()

        return self._plugins.setdefault(plugin_type, ())
Beispiel #16
0
 def _save_user_state(self, user_name, user_state):
     """ Saves the state for the passed user to the session database """
     if user_state:
         user_state_json = json.dumps(user_state)
         user_settings = getattr(self._dmd.ZenUsers, user_name)
         state_container = getattr(user_settings, '_browser_state', None)
         if isinstance(state_container,
                       basestring) or state_container is None:
             state_container = PersistentMapping()
             user_settings._browser_state = state_container
         if user_state_json != state_container.get('state', ''):
             state_container['state'] = user_state_json
Beispiel #17
0
def fixArchetypesTool(portal, out):
    at = portal.archetype_tool

    if not hasattr(at, '_templates'):
        # They come in pairs
        at._templates = PersistentMapping()
        at._registeredTemplates = PersistentMapping()

    if not hasattr(at, 'catalog_map'):
        at.catalog_map = PersistentMapping()

    install_uidcatalog(out, portal)
    def getSelectedCriteria(self, bib_type=None):

        # migrate CMFBAT v0.8 duplicates engine, mending a linguistic fault-pas
        if shasattr(self, 'imp_criterias'):
            print 'CMFBibliographyAT: performing duplicates engine property update - v0.8 -> v0.9 (getSelectedCriteria of %s)' % '/'.join(
                self.getId())
            self.duplicates_criteria = PersistentMapping()
            self.duplicates_criteria = copy.deepcopy(self.imp_criterias)
            self.criteriaUpdated = self.criteriasUpdated
            try:
                delattr(self, 'imp_criterias')
            except:
                pass
            try:
                delattr(self, 'criteriasUpdated')
            except:
                pass

        # first call? initialize self.duplicates_criteria
        bib_tool = getToolByName(self, 'portal_bibliography')
        if not shasattr(self,
                        'duplicates_criteria') or not self.duplicates_criteria:

            if self.getId() == bib_tool.getId():
                for reference_type in bib_tool.getReferenceTypes():
                    self.duplicates_criteria[reference_type] = PersistentList(
                        self._default_duplicates_criteria)
                self.criteriaUpdated = True
            else:
                self.duplicates_criteria = bib_tool.getSelectedCriteria()
                self.criteriaUpdated = True

        if not shasattr(self, '_criteria') or not self._criteria:
            self.initCriteria()

        # make sure, our selected criteria are in sync with available criteria
        duplicates_criteria = {}
        for key in self._criteria.keys():
            duplicates_criteria[key] = [
                criterion for criterion in self._criteria[key]
                if self.duplicates_criteria.has_key(key) and (
                    criterion in self.duplicates_criteria[key])
            ]

        if bib_type:
            try:
                duplicates_criteria[bib_type]
            except KeyError:
                return False
            return duplicates_criteria[bib_type]
        else:
            return duplicates_criteria
Beispiel #19
0
 def test_catch_extra_attribute(self):
     # The mapper for PersistentMappings doesn't allow an
     # extra attribute.
     classification = None
     ob = PersistentMapping()
     ob.extra = '678'
     ob['a'] = 'b'
     ob['c'] = 'd'
     obj_db = MockObjectDatabase()
     m = self.conf.mappers["pm"]
     event = SerializationEvent(
         self.conf, m, '', classification, obj_db, ob)
     self.assertRaises(SerializationError, m.serializer.serialize, event)
Beispiel #20
0
    def setBrowserState(self, state):
        """
        Save the browser state for the current user.

        @param state: The browser state as a JSON-encoded string
        @type state: str
        """
        userSettings = self.context.dmd.ZenUsers.getUserSettings()
        state_container = getattr(userSettings, '_browser_state', None)
        if isinstance(state_container, basestring) or state_container is None:
            state_container = PersistentMapping()
            userSettings._browser_state = state_container
        if state != state_container.get('state', ''):
            state_container['state'] = state
Beispiel #21
0
    def __init__(self, plugin_type_info=()):

        if isinstance(plugin_type_info, basestring):
            # some tool is passing us our ID.
            raise ValueError('Must pass a sequence of plugin info dicts!')

        self._plugin_types = [x[0] for x in plugin_type_info]
        self._plugin_type_info = PersistentMapping()
        for interface in plugin_type_info:
            self._plugin_type_info[interface[0]] = {
                'id': interface[1],
                'title': interface[2],
                'description': interface[3]
            }
Beispiel #22
0
    def setBrowserState(self, state):
        """
        Save the browser state for the current user.

        @param state: The browser state as a JSON-encoded string
        @type state: str
        """
        userSettings = self.context.dmd.ZenUsers.getUserSettings()
        state_container = getattr(userSettings, '_browser_state', None)
        if isinstance(state_container, basestring) or state_container is None:
            state_container = PersistentMapping()
            userSettings._browser_state = state_container
        if state != state_container.get('state', ''):
            state_container['state'] = state
Beispiel #23
0
    def create_frozen_state(self, workflow, **parameters):
        """
        create a 'frozen' state
        """
        if 'frozen' not in workflow.states:
            workflow.states.addState('frozen')

        frozen_state = workflow.states['frozen']
        default_mapping = workflow.states.objectValues()[0].permission_roles.copy()
        frozen_state.title = 'frozen'
        frozen_state.permission_roles = default_mapping
        frozen_state.group_roles = PersistentMapping()
        frozen_state.var_values = PersistentMapping()
        frozen_state.transitions = ()
Beispiel #24
0
 def test_get_serial_detects_new_objects(self):
     # Verifies the behavior of _get_serial() and _set_serial().
     conn1 = self.db.open()
     try:
         ob = self._write_basic_object(conn1)
         self.assertNotEqual(conn1._get_serial(ob), '\0' * 8)
         # Replace the object and verify it gets a new serial.
         ob1 = PersistentMapping()
         ob1.strdata = 'cba'
         ob1._p_oid = conn1.root()['TestRoot']._p_oid
         conn1.root()['TestRoot'] = ob1
         self.assertEqual(conn1._get_serial(ob1), '\0' * 8)
     finally:
         conn1.close()
Beispiel #25
0
 def test_get_serial_detects_new_objects(self):
     # Verifies the behavior of _get_serial() and _set_serial().
     conn1 = self.db.open()
     try:
         ob = self._write_basic_object(conn1)
         self.assertNotEqual(conn1._get_serial(ob), '\0' * 8)
         # Replace the object and verify it gets a new serial.
         ob1 = PersistentMapping()
         ob1.strdata = 'cba'
         ob1._p_oid = conn1.root()['TestRoot']._p_oid
         conn1.root()['TestRoot'] = ob1
         self.assertEqual(conn1._get_serial(ob1), '\0' * 8)
     finally:
         conn1.close()
Beispiel #26
0
    def test_copy_of(self):
        # Verifies the functionality of zodb_copy().
        ob1 = PersistentMapping()
        ob1._p_oid = 'xxx'
        self.assertEqual(ob1._p_oid, 'xxx')  # Precondition
        ob1['fish'] = PersistentMapping()
        ob1['fish']['trout'] = 1
        ob1['fish']['herring'] = 2

        ob2 = zodb_copy(ob1)
        self.assert_(ob2 is not ob1)
        self.assert_(ob2['fish'] is not ob1['fish'])
        self.assert_(ob2._p_oid is None)
        self.assertEqual(list(ob2.keys()), ['fish'])
        self.assertEqual(len(ob2['fish'].keys()), 2)
Beispiel #27
0
    def test_copy_of(self):
        # Verifies the functionality of zodb_copy().
        ob1 = PersistentMapping()
        ob1._p_oid = 'xxx'
        self.assertEqual(ob1._p_oid, 'xxx')  # Precondition
        ob1['fish'] = PersistentMapping()
        ob1['fish']['trout'] = 1
        ob1['fish']['herring'] = 2

        ob2 = zodb_copy(ob1)
        self.assert_(ob2 is not ob1)
        self.assert_(ob2['fish'] is not ob1['fish'])
        self.assert_(ob2._p_oid is None)
        self.assertEqual(list(ob2.keys()), ['fish'])
        self.assertEqual(len(ob2['fish'].keys()), 2)
Beispiel #28
0
    def setRoleMapping(self, portal_role, userfolder_role, REQUEST=None):
        """
        set the mapping of roles between roles understood by
        the portal and roles coming from outside user sources
        """
        if not hasattr(self, 'role_map'): self.role_map = PersistentMapping()

        if len(userfolder_role) < 1:
            del self.role_map[portal_role]
        else:
            self.role_map[portal_role] = userfolder_role

        return MessageDialog(title='Mapping updated',
                             message='The Role mappings have been updated',
                             action='manage_mapRoles')
 def setMultiEntryTransition(self, transition_url, max_entry_number):
     """ Set a transition as multiple - i.e max_entry_number of forms
     which will be rendered. This method is called in after scripts
     and usually this number is set by user in a web form. """
     if getattr(aq_base(self), '_multi_entry_transitions', None) is None:
         self._multi_entry_transitions = PersistentMapping()
     self._multi_entry_transitions[transition_url] = max_entry_number
 def initCriteria(self):
     """ initialize the dictionary of import criteria
     for each bibliography type
     """
     # this is a migration 0.8 -> 0.9 fix:
     if not shasattr(self, '_criteria'):
         self._criteria = PersistentMapping()
     bib_tool = getToolByName(self, 'portal_bibliography')
     has = self._criteria_names.has_key
     for bib_type in bib_tool.getBibliographyContentTypes():
         bibname = bib_type['name']
         self._criteria[bibname] = [criteria for criteria in self._nonmeta_criteria]
         #adds all meta_data as criteria for each bibliography type
         for field in bib_type['schema'].fields():
             field_name = field.getName()
             if field_name in self._ignored_criteria:
                 continue
             if not shasattr(field, 'is_duplicates_criterion'):
                 continue
             if not field.is_duplicates_criterion:
                 continue
             if has(field_name):
                 self._criteria[bibname].append(self._criteria_names[field_name])
             else :
                 self._criteria[bibname].append(field_name)
         self._criteria[bibname].sort()
         self._criteria[bibname] = tuple(self._criteria[bibname])
Beispiel #31
0
def _initDCWorkflowWorklists(workflow, worklists):
    """ Initialize DCWorkflow worklists
    """
    from Products.DCWorkflow.Worklists import WorklistDefinition

    for w_info in worklists:

        id = str(w_info['worklist_id'])  # no unicode!
        if not workflow.worklists.has_key(id):
            w = WorklistDefinition(id)
            workflow.worklists._setObject(id, w)
        w = workflow.worklists._getOb(id)

        action = w_info['action']

        guard = w_info['guard']
        props = {
            'guard_roles': ';'.join(guard['roles']),
            'guard_permissions': ';'.join(guard['permissions']),
            'guard_groups': ';'.join(guard['groups']),
            'guard_expr': guard['expression']
        }

        w.setProperties(description=w_info['description'],
                        actbox_name=action['name'],
                        actbox_url=action['url'],
                        actbox_category=action['category'],
                        actbox_icon=action.get('icon', ''),
                        props=props)

        w.var_matches = PersistentMapping()
        for k, v in w_info['match'].items():
            w.var_matches[str(k)] = tuple([str(x) for x in v])
    def setChainForPortalTypes(self,
                               pt_names,
                               chain,
                               verify=True,
                               REQUEST=None):
        """ Set a chain for specific portal types.
        """
        cbt = self._chains_by_type
        if cbt is None:
            self._chains_by_type = cbt = PersistentMapping()

        if isinstance(chain, six.string_types):
            if chain == '(Default)':
                chain = None
            else:
                chain = [wf.strip() for wf in chain.split(',') if wf.strip()]

        if chain is None:
            for type_id in pt_names:
                if type_id in cbt:
                    del cbt[type_id]
            return

        ti_ids = [t.getId() for t in self._listTypeInfo()]

        for type_id in pt_names:
            if verify and not (type_id in ti_ids):
                continue
            cbt[type_id] = tuple(chain)
 def setGlobalConfigurationAttr(self, **kw):
     """ Set global business configuration attribute. """
     if getattr(aq_base(self), '_global_configuration_attributes',
                None) is None:
         self._global_configuration_attributes = PersistentMapping()
     for key, value in kw.items():
         self._global_configuration_attributes[key] = value
Beispiel #34
0
    def get_po_header(self, lang):
        """ """
        # For backwards compatibility
        if not hasattr(aq_base(self), '_po_headers'):
            self._po_headers = PersistentMapping()

        return self._po_headers.get(lang, empty_po_header)
 def set(self, status):
     history = getattr(self.context, 'workflow_history', None)
     if history is None:
         history = self.context.workflow_history = PersistentMapping()
     wfh = list(history.get(self.wf_id, ()))
     wfh.append(status)
     history[self.wf_id] = tuple(wfh)
Beispiel #36
0
    def setChain(self, portal_type, chain, REQUEST=None):
        """Set the chain for a portal type.

           @type chain: tuple of strings or None
           @param chain: A tuple of workflow ids to be set for the portal type.
                         A few special values exsist:
                           - C{None}: Acquire chain from a policy above,
                                      ultimatly from the portal workflow settings.
                           - C{()} (empty tuple): No workflow for this type.
                           - C{('default',)}: Use the configured default workflow.
        """
        # Verify input data
        if portal_type not in [pt.id for pt in self._listTypeInfo()]:
            raise ValueError("'%s' is not a valid portal type." % portal_type)

        if isinstance(chain, six.string_types):
            chain = map(lambda x: x.strip(), chain.split(','))

        wftool = getToolByName(self, 'portal_workflow')
        cbt = self._chains_by_type
        if cbt is None:
            self._chains_by_type = cbt = PersistentMapping()

        # if chain is None or default, we remove the entry
        if chain is None:
            if portal_type in cbt:
                del cbt[portal_type]
        elif len(chain) == 1 and chain[0] == DEFAULT_CHAIN:
            cbt[portal_type] = chain
        else:
            for wf_id in chain:
                if wf_id != '' and not wftool.getWorkflowById(wf_id):
                    raise ValueError("'%s' is not a workflow ID.\nchain: %s" %
                                     (wf_id, repr(chain)))
            cbt[portal_type] = tuple(chain)
Beispiel #37
0
    def wl_lockmapping(self, killinvalids=0, create=0):
        """ if 'killinvalids' is 1, locks who are no longer valid
        will be deleted """

        try:
            locks = getattr(self, '_dav_writelocks', None)
        except Exception:
            locks = None

        if locks is None:
            if create:
                locks = self._dav_writelocks = PersistentMapping()
            else:
                # Don't generate a side effect transaction.
                locks = {}
            return locks
        elif killinvalids:
            # Delete invalid locks
            for token, lock in list(locks.items()):
                if not lock.isValid():
                    del locks[token]
            if (not locks) and hasattr(aq_base(self),
                                       '__no_valid_write_locks__'):
                self.__no_valid_write_locks__()
            return locks
        else:
            return locks
Beispiel #38
0
    def __init__(self, id, title, sourcelang, languages):
        self.id = id

        self.title = title

        # Language Manager data
        self._languages = tuple(languages)
        self._default_language = sourcelang

        # Here the message translations are stored
        self._messages = PersistentMapping()

        # Data for the PO files headers
        self._po_headers = PersistentMapping()
        for lang in self._languages:
            self._po_headers[lang] = empty_po_header
Beispiel #39
0
 def setRankForCategory(self, category, rank):
     """Set the object's rank for the specified category
     """
     if not hasattr(self, '_categoryRanks') \
         or not isinstance(self._categoryRanks, PersistentMapping):
         self._categoryRanks = PersistentMapping()
     self._categoryRanks[category] = rank
 def setStatusOf(self, wf_id, ob, status):
     """Invoked by workflow definitions.  Appends to the workflow history.
     """
     ob_id = self._getId(ob, 1)
     assert ob_id, 'No version history ID available'
     repo = self._getRepository()
     h = repo.getHistory(ob_id)
     if h is None:
         h = PersistentMapping()
         repo.setHistory(ob_id, h)
     wfh = h.get(wf_id)
     if wfh is not None:
         wfh = list(wfh)
     else:
         wfh = []
     wfh.append(status)
     h[wf_id] = tuple(wfh)
Beispiel #41
0
 def test_serial_cleanup(self):
     # Verify that _set_serial() cleans up.
     conn1 = self.db.open()
     try:
         conn1.serial_cleanup_threshold = 10
         for n in range(conn1.serial_cleanup_threshold + 1):
             new_ob = PersistentMapping()
             new_ob._p_oid = 'fake_oid_' + str(n)
             old_size = len(conn1._serials or ())
             conn1._set_serial(new_ob, '01234567')
             new_size = len(conn1._serials)
             if new_size < old_size:
                 # Cleaned up.  Success.
                 break
         else:
             self.fail("_set_serial() did not clean up")
     finally:
         conn1.close()
Beispiel #42
0
 def _prepare_root(self):
     osio = self._get_osio()
     oid = osio.conf.oid_gen.root_oid
     try:
         self[oid]
     except (KeyError, LoadError):
         # Create the root object.
         from Persistence import PersistentMapping
         root = PersistentMapping()
         root._p_jar = self
         root._p_changed = 1
         root._p_oid = oid
         t = transaction.Transaction()
         t.note('Initial database creation')
         self.tpc_begin(t)
         self.commit(root, t)
         self.tpc_vote(t)
         self.tpc_finish(t)
Beispiel #43
0
    def listPolicies(self):
        """ return the list of defined policies

        a policy is a 2-uple (output_mime_type, [list of required transforms])
        """
        # XXXFIXME: backward compat, should be removed latter
        if not hasattr(self, '_policies'):
            self._policies = PersistentMapping()
        return self._policies.items()
 def setCriteria(self, duplicates_criteria):
     """update criteria for all bibliography types"""
     if not duplicates_criteria:
         duplicates_criteria = {}
         bib_tool = getToolByName(self, 'portal_bibliography')
         for key in bib_tool.getReferenceTypes():
             duplicates_criteria[key] = []
     self.duplicates_criteria = PersistentMapping(duplicates_criteria)
     self.criteriaUpdated = True
    def __init__(self, id=None):
        if id is not None:
            assert id == self.id
        self.encodings_map = encodings_map.copy()
        self.suffix_map = suffix_map.copy()
        # Major key -> minor IMimetype objects
        self._mimetypes = PersistentMapping()
        # ext -> IMimetype mapping
        self.extensions = PersistentMapping()
        # glob -> (regex, mimetype) mapping
        self.globs = OOBTree()
        self.manage_addProperty("defaultMimetype", "text/plain", "string")
        self.manage_addProperty("unicodePolicies", "strict ignore replace", "tokens")
        self.manage_addProperty("unicodePolicy", "unicodePolicies", "selection")
        self.manage_addProperty("fallbackEncoding", "latin1", "string")

        # initialize mime types
        initialize(self)
        self._new_style_mtr = 1
Beispiel #46
0
    def __init__( self, plugin_type_info ):

        self._plugin_types = [x[0] for x in plugin_type_info]
        self._plugin_type_info = PersistentMapping()
        for interface in plugin_type_info:
            self._plugin_type_info[interface[0]] = { 
                  'id': interface[1]
                , 'title': interface[2]
                , 'description': interface[3]
                }
Beispiel #47
0
    def _getPlugins(self, plugin_type):

        parent = aq_parent(aq_inner(self))

        if plugin_type not in self._plugin_types:
            raise KeyError, plugin_type

        if self._plugins is None:
            self._plugins = PersistentMapping()

        return self._plugins.setdefault(plugin_type, ())
Beispiel #48
0
    def __init__(self, plugin_type_info=()):

        if isinstance(plugin_type_info, basestring):
            # some tool is passing us our ID.
            raise ValueError('Must pass a sequence of plugin info dicts!')

        self._plugin_types = [x[0] for x in plugin_type_info]
        self._plugin_type_info = PersistentMapping()
        for interface in plugin_type_info:
            self._plugin_type_info[interface[0]] = { 
                  'id': interface[1]
                , 'title': interface[2]
                , 'description': interface[3]
                }
Beispiel #49
0
    def setRoleMapping(self, portal_role, userfolder_role, REQUEST=None):
        """
        set the mapping of roles between roles understood by
        the portal and roles coming from outside user sources
        """
        if not hasattr(self, 'role_map'): self.role_map = PersistentMapping()

        if len(userfolder_role) < 1:
            del self.role_map[portal_role]
        else:
            self.role_map[portal_role] = userfolder_role

        return MessageDialog(
               title  ='Mapping updated',
               message='The Role mappings have been updated',
               action ='manage_mapRoles')
    def __init__(self, id, title, languages=('en', )):

        self.id = id
        self.title = title

        # Language Manager data
        self._languages = tuple(languages)

        # We suppose all zope/portal products are written in English
        # therefore we consider all new messages in English
        # Default language in Catalog is always 'en', thus it can be different
        # from the default language of the portal
        self._default_language = 'en' # self._languages[0]

        # Here the message translations are stored
        self._messages = PersistentMapping()
        self._po_headers = PersistentMapping()
Beispiel #51
0
 def __init__(self, id, **kwargs):
     self._data = PersistentMapping()
     extres = id.startswith('http://') or id.startswith('https://')
     if id.startswith('/') or id.endswith('/') or ('//' in id and not extres):
         raise ValueError("Invalid Resource ID: %s" % id)
     self._data['id'] = id
     expression = kwargs.get('expression', '')
     self.setExpression(expression)
     self._data['authenticated'] = kwargs.get('authenticated', False)
     self._data['enabled'] = kwargs.get('enabled', True)
     self._data['cookable'] = kwargs.get('cookable', True)
     self._data['cacheable'] = kwargs.get('cacheable', True)
     self._data['conditionalcomment'] = kwargs.get('conditionalcomment','')
     self.isExternal = extres
     if extres:
         self._data['cacheable'] = False #External resources are NOT cacheable
         self._data['cookable'] = False #External resources are NOT mergable
 def __init__(self, id, **kwargs):
     self._data = PersistentMapping()
     extres = id.startswith("http://") or id.startswith("https://")
     if id.startswith("/") or id.endswith("/") or ("//" in id and not extres):
         raise ValueError("Invalid Resource ID: %s" % id)
     self._data["id"] = id
     expression = kwargs.get("expression", "")
     self.setExpression(expression)
     self._data["authenticated"] = kwargs.get("authenticated", False)
     self._data["enabled"] = kwargs.get("enabled", True)
     self._data["cookable"] = kwargs.get("cookable", True)
     self._data["cacheable"] = kwargs.get("cacheable", True)
     self._data["conditionalcomment"] = kwargs.get("conditionalcomment", "")
     self._data["bundle"] = kwargs.get("bundle", "default")
     self.isExternal = extres
     if extres:
         self._data["cacheable"] = False  # External resources are NOT cacheable
         self._data["cookable"] = False  # External resources are NOT mergable
    def getSelectedCriteria(self, bib_type = None):

        # migrate CMFBAT v0.8 duplicates engine, mending a linguistic fault-pas
        if shasattr(self, 'imp_criterias'):
            print 'CMFBibliographyAT: performing duplicates engine property update - v0.8 -> v0.9 (getSelectedCriteria of %s)' % '/'.join(self.getId())
            self.duplicates_criteria = PersistentMapping()
            self.duplicates_criteria = copy.deepcopy(self.imp_criterias)
            self.criteriaUpdated = self.criteriasUpdated
            try: delattr(self, 'imp_criterias')
            except: pass
            try: delattr(self, 'criteriasUpdated')
            except: pass

        # first call? initialize self.duplicates_criteria
        bib_tool = getToolByName(self, 'portal_bibliography')
        if not shasattr(self, 'duplicates_criteria') or not self.duplicates_criteria:

            if self.getId() == bib_tool.getId():
                for reference_type in bib_tool.getReferenceTypes():
                    self.duplicates_criteria[reference_type] = PersistentList(self._default_duplicates_criteria)
                self.criteriaUpdated = True
            else:
                self.duplicates_criteria = bib_tool.getSelectedCriteria()
                self.criteriaUpdated = True

        if not shasattr(self, '_criteria') or not self._criteria:
            self.initCriteria()

        # make sure, our selected criteria are in sync with available criteria
        duplicates_criteria = {}
        for key in self._criteria.keys():
            duplicates_criteria[key] = [ criterion for criterion in self._criteria[key] if self.duplicates_criteria.has_key(key) and (criterion in self.duplicates_criteria[key]) ]

        if bib_type:
            try:
                duplicates_criteria[bib_type]
            except KeyError:
                return False
            return duplicates_criteria[bib_type]
        else:
            return duplicates_criteria
Beispiel #54
0
    def setProperties(self, description,
                      actbox_name='', actbox_url='', actbox_category='global',
                      actbox_icon='', props=None, REQUEST=None):
        '''
        '''
        if props is None:
            props = REQUEST
        self.description = str(description)
        for key in self.getAvailableCatalogVars():
            # Populate var_matches.
            fieldname = 'var_match_%s' % key
            v = props.get(fieldname, '')
            if v:
                if not self.var_matches:
                    self.var_matches = PersistentMapping()

                if tales_re.match(v).group(1):
                    # Found a TALES prefix
                    self.var_matches[key] = Expression(v)
                else:
                    # Falling back to formatted string
                    v = [ var.strip() for var in v.split(';') ]
                    self.var_matches[key] = tuple(v)

            else:
                if self.var_matches and self.var_matches.has_key(key):
                    del self.var_matches[key]
        self.actbox_name = str(actbox_name)
        self.actbox_url = str(actbox_url)
        self.actbox_category = str(actbox_category)
        self.actbox_icon = str(actbox_icon)
        g = Guard()
        if g.changeFromProperties(props or REQUEST):
            self.guard = g
        else:
            self.guard = None
        if REQUEST is not None:
            return self.manage_properties(REQUEST, 'Properties changed.')
class Resource(Persistent):
    security = ClassSecurityInfo()

    def __init__(self, id, **kwargs):
        self._data = PersistentMapping()
        extres = id.startswith('http://') or id.startswith('https://')
        if id.startswith('/') or id.endswith('/') or ('//' in id and not extres):
            raise ValueError("Invalid Resource ID: %s" % id)
        self._data['id'] = id
        expression = kwargs.get('expression', '')
        self.setExpression(expression)
        self._data['authenticated'] = kwargs.get('authenticated', False)
        self._data['enabled'] = kwargs.get('enabled', True)
        self._data['cookable'] = kwargs.get('cookable', True)
        self._data['cacheable'] = kwargs.get('cacheable', True)
        self._data['conditionalcomment'] = kwargs.get('conditionalcomment','')
        self._data['bundle'] = kwargs.get('bundle', 'default')
        self.isExternal = extres
        if extres:
            self._data['cacheable'] = False #External resources are NOT cacheable
            self._data['cookable'] = False #External resources are NOT mergable

    def copy(self):
        result = self.__class__(self.getId())
        for key, value in self._data.items():
            if key != 'id':
                result._data[key] = value
        return result

    security.declarePublic('getId')
    def getId(self):
        return self._data['id']

    security.declarePublic('getQuotedId')
    def getQuotedId(self):
        return quote_plus(self._data['id'])

    security.declareProtected(permissions.ManagePortal, '_setId')
    def _setId(self, id):
        if id.startswith('/') or id.endswith('/') or (
                ('//' in id) and not self.isExternalResource()):
            raise ValueError("Invalid Resource ID: %s" %id)
        self._data['id'] = id

    security.declarePublic('getCookedExpression')
    def getCookedExpression(self):
        # Automatic inline migration of expressions
        if 'cooked_expression' not in self._data:
            expr = Expression(self._data['expression'])
            self._data['cooked_expression'] = expr
        return self._data['cooked_expression']

    security.declarePublic('getExpression')
    def getExpression(self):
        return self._data['expression']

    security.declareProtected(permissions.ManagePortal, 'setExpression')
    def setExpression(self, expression):
        # Update the cooked expression
        self._data['cooked_expression'] = Expression( expression )
        self._data['expression'] = expression

    security.declarePublic('getAuthenticated')
    def getAuthenticated(self):
        # Automatic inline migration
        if 'authenticated' not in self._data:
            self._data['authenticated'] = False
        return bool(self._data['authenticated'])

    security.declareProtected(permissions.ManagePortal, 'setAuthenticated')
    def setAuthenticated(self, authenticated):
        self._data['authenticated'] = authenticated

    security.declarePublic('getEnabled')
    def getEnabled(self):
        return bool(self._data['enabled'])

    security.declareProtected(permissions.ManagePortal, 'setEnabled')
    def setEnabled(self, enabled):
        self._data['enabled'] = enabled

    security.declarePublic('getCookable')
    def getCookable(self):
        return self._data['cookable']

    security.declareProtected(permissions.ManagePortal, 'setCookable')
    def setCookable(self, cookable):
        if self.isExternalResource() and cookable:
            raise ValueError("External Resources cannot be merged")
        self._data['cookable'] = cookable

    security.declarePublic('getCacheable')
    def getCacheable(self):
        # as this is a new property, old instance might not have that value, so
        # return True as default
        return self._data.get('cacheable', True)

    security.declareProtected(permissions.ManagePortal, 'setCacheable')
    def setCacheable(self, cacheable):
        if self.isExternalResource() and cacheable:
            raise ValueError("External Resources are not cacheable")
        self._data['cacheable'] = cacheable

    security.declarePublic('getConditionalcomment')
    def getConditionalcomment(self):
        # New property, return blank if the old instance doesn't have that value
        return self._data.get('conditionalcomment','')

    security.declareProtected(permissions.ManagePortal, 'setConditionalcomment')
    def setConditionalcomment(self, conditionalcomment):
        self._data['conditionalcomment'] = conditionalcomment

    security.declarePublic('isExternalResource')
    def isExternalResource(self):
        return getattr(self, 'isExternal', False)

    security.declarePublic('getBundle')
    def getBundle(self):
        return self._data.get('bundle', None) or 'default'
    
    security.declareProtected(permissions.ManagePortal, 'setBundle')
    def setBundle(self, bundle):
        self._data['bundle'] = bundle
class Resource(Persistent):
    security = ClassSecurityInfo()

    def __init__(self, id, **kwargs):
        self._data = PersistentMapping()
        extres = id.startswith("http://") or id.startswith("https://")
        if id.startswith("/") or id.endswith("/") or ("//" in id and not extres):
            raise ValueError("Invalid Resource ID: %s" % id)
        self._data["id"] = id
        expression = kwargs.get("expression", "")
        self.setExpression(expression)
        self._data["authenticated"] = kwargs.get("authenticated", False)
        self._data["enabled"] = kwargs.get("enabled", True)
        self._data["cookable"] = kwargs.get("cookable", True)
        self._data["cacheable"] = kwargs.get("cacheable", True)
        self._data["conditionalcomment"] = kwargs.get("conditionalcomment", "")
        self._data["bundle"] = kwargs.get("bundle", "default")
        self.isExternal = extres
        if extres:
            self._data["cacheable"] = False  # External resources are NOT cacheable
            self._data["cookable"] = False  # External resources are NOT mergable

    def copy(self):
        result = self.__class__(self.getId())
        for key, value in self._data.items():
            if key != "id":
                result._data[key] = value
        return result

    security.declarePublic("getId")

    def getId(self):
        return self._data["id"]

    security.declarePublic("getQuotedId")

    def getQuotedId(self):
        return quote_plus(self._data["id"])

    security.declareProtected(permissions.ManagePortal, "_setId")

    def _setId(self, id):
        if id.startswith("/") or id.endswith("/") or (("//" in id) and not self.isExternalResource()):
            raise ValueError("Invalid Resource ID: %s" % id)
        self._data["id"] = id

    security.declarePublic("getCookedExpression")

    def getCookedExpression(self):
        # Automatic inline migration of expressions
        if "cooked_expression" not in self._data:
            expr = Expression(self._data["expression"])
            self._data["cooked_expression"] = expr
        return self._data["cooked_expression"]

    security.declarePublic("getExpression")

    def getExpression(self):
        return self._data["expression"]

    security.declareProtected(permissions.ManagePortal, "setExpression")

    def setExpression(self, expression):
        # Update the cooked expression
        self._data["cooked_expression"] = Expression(expression)
        self._data["expression"] = expression

    security.declarePublic("getAuthenticated")

    def getAuthenticated(self):
        # Automatic inline migration
        if "authenticated" not in self._data:
            self._data["authenticated"] = False
        return bool(self._data["authenticated"])

    security.declareProtected(permissions.ManagePortal, "setAuthenticated")

    def setAuthenticated(self, authenticated):
        self._data["authenticated"] = authenticated

    security.declarePublic("getEnabled")

    def getEnabled(self):
        return bool(self._data["enabled"])

    security.declareProtected(permissions.ManagePortal, "setEnabled")

    def setEnabled(self, enabled):
        self._data["enabled"] = enabled

    security.declarePublic("getCookable")

    def getCookable(self):
        return self._data["cookable"]

    security.declareProtected(permissions.ManagePortal, "setCookable")

    def setCookable(self, cookable):
        if self.isExternalResource() and cookable:
            raise ValueError("External Resources cannot be merged")
        self._data["cookable"] = cookable

    security.declarePublic("getCacheable")

    def getCacheable(self):
        # as this is a new property, old instance might not have that value, so
        # return True as default
        return self._data.get("cacheable", True)

    security.declareProtected(permissions.ManagePortal, "setCacheable")

    def setCacheable(self, cacheable):
        if self.isExternalResource() and cacheable:
            raise ValueError("External Resources are not cacheable")
        self._data["cacheable"] = cacheable

    security.declarePublic("getConditionalcomment")

    def getConditionalcomment(self):
        # New property, return blank if the old instance doesn't have that value
        return self._data.get("conditionalcomment", "")

    security.declareProtected(permissions.ManagePortal, "setConditionalcomment")

    def setConditionalcomment(self, conditionalcomment):
        self._data["conditionalcomment"] = conditionalcomment

    security.declarePublic("isExternalResource")

    def isExternalResource(self):
        return getattr(self, "isExternal", False)

    security.declarePublic("getBundle")

    def getBundle(self):
        return self._data.get("bundle", None) or "default"

    security.declareProtected(permissions.ManagePortal, "setBundle")

    def setBundle(self, bundle):
        self._data["bundle"] = bundle
class ArchetypeTool(UniqueObject, ActionProviderBase,
                    SQLStorageConfig, Folder):
    """Archetypes tool, manage aspects of Archetype instances.
    """
    id = TOOL_NAME
    meta_type = TOOL_NAME.title().replace('_', ' ')

    implements(IArchetypeTool)

    isPrincipiaFolderish = True  # Show up in the ZMI

    security = ClassSecurityInfo()

    meta_types = all_meta_types = ()

    manage_options = (
        (
            {'label': 'Types',
             'action': 'manage_debugForm',
             },

            {'label': 'Catalogs',
             'action': 'manage_catalogs',
             },

            {'label': 'Templates',
             'action': 'manage_templateForm',
             },

            {'label': 'UIDs',
             'action': 'manage_uids',
             },

            {'label': 'Update Schema',
             'action': 'manage_updateSchemaForm',
             },

            {'label': 'Migration',
             'action': 'manage_migrationForm',
             },

        ) + SQLStorageConfig.manage_options
    )

    security.declareProtected(permissions.ManagePortal,
                              'manage_uids')
    manage_uids = PageTemplateFile('viewContents', _www)
    security.declareProtected(permissions.ManagePortal,
                              'manage_templateForm')
    manage_templateForm = PageTemplateFile('manageTemplates', _www)
    security.declareProtected(permissions.ManagePortal,
                              'manage_debugForm')
    manage_debugForm = PageTemplateFile('generateDebug', _www)
    security.declareProtected(permissions.ManagePortal,
                              'manage_updateSchemaForm')
    manage_updateSchemaForm = PageTemplateFile('updateSchemaForm', _www)
    security.declareProtected(permissions.ManagePortal,
                              'manage_migrationForm')
    manage_migrationForm = PageTemplateFile('migrationForm', _www)
    security.declareProtected(permissions.ManagePortal,
                              'manage_dumpSchemaForm')
    manage_dumpSchemaForm = PageTemplateFile('schema', _www)
    security.declareProtected(permissions.ManagePortal,
                              'manage_catalogs')
    manage_catalogs = PageTemplateFile('manage_catalogs', _www)

    def __init__(self):
        self._schemas = PersistentMapping()
        self._templates = PersistentMapping()
        self._registeredTemplates = PersistentMapping()
        # meta_type -> [names of CatalogTools]
        self.catalog_map = PersistentMapping()
        self.catalog_map['Reference'] = []  # References not in portal_catalog
        # DM (avoid persistency bug): "_types" now maps known schemas to
        # signatures
        self._types = {}

    security.declareProtected(permissions.ManagePortal,
                              'manage_dumpSchema')

    def manage_dumpSchema(self, REQUEST=None):
        """XML Dump Schema of passed in class.
        """
        from Products.Archetypes.Schema import getSchemata
        package = REQUEST.get('package', '')
        type_name = REQUEST.get('type_name', '')
        spec = self.getTypeSpec(package, type_name)
        type = self.lookupType(package, type_name)
        options = {}
        options['classname'] = spec
        options['schematas'] = getSchemata(type['klass'])
        REQUEST.RESPONSE.setHeader('Content-Type', 'text/xml')
        return self.manage_dumpSchemaForm(**options)

    # Template Management
    # Views can be pretty generic by iterating the schema so we don't
    # register by type anymore, we just create per site selection
    # lists
    #
    # We keep two lists, all register templates and their
    # names/titles and the mapping of type to template bindings both
    # are persistent
    security.declareProtected(permissions.ManagePortal,
                              'registerTemplate')

    def registerTemplate(self, template, name=None):
        # Lookup the template by name
        if not name:
            obj = self.unrestrictedTraverse(template, None)
            try:
                name = obj.title_or_id()
            except:
                name = template

        self._registeredTemplates[template] = name

    security.declareProtected(permissions.View, 'lookupTemplates')

    def lookupTemplates(self, instance_or_portaltype=None):
        """Lookup templates by giving an instance or a portal_type.

        Returns a DisplayList.
        """
        results = []
        if not isinstance(instance_or_portaltype, basestring):
            portal_type = instance_or_portaltype.getTypeInfo().getId()
        else:
            portal_type = instance_or_portaltype
        try:
            templates = self._templates[portal_type]
        except KeyError:
            return DisplayList()
            # XXX Look this up in the types tool later
            # self._templates[instance] = ['base_view',]
            # templates = self._templates[instance]
        for t in templates:
            results.append((t, self._registeredTemplates[t]))

        return DisplayList(results).sortedByValue()

    security.declareProtected(permissions.View, 'listTemplates')

    def listTemplates(self):
        """Lists all the templates.
        """
        return DisplayList(self._registeredTemplates.items()).sortedByValue()

    security.declareProtected(permissions.ManagePortal, 'bindTemplate')

    def bindTemplate(self, portal_type, templateList):
        """Creates binding between a type and its associated views.
        """
        self._templates[portal_type] = templateList

    security.declareProtected(permissions.ManagePortal,
                              'manage_templates')

    def manage_templates(self, REQUEST=None):
        """Sets all the template/type mappings.
        """
        prefix = 'template_names_'
        for key in REQUEST.form.keys():
            if key.startswith(prefix):
                k = key[len(prefix):]
                v = REQUEST.form.get(key)
                self.bindTemplate(k, v)

        add = REQUEST.get('addTemplate')
        name = REQUEST.get('newTemplate')
        if add and name:
            self.registerTemplate(name)

        return REQUEST.RESPONSE.redirect(self.absolute_url() + '/manage_templateForm')

    security.declareProtected(permissions.View, 'typeImplementsInterfaces')

    def typeImplementsInterfaces(self, type, interfaces):
        """Checks if an type uses one of the given interfaces.
        """
        if isinstance(type, dict) and 'klass' in type:
            type = type['klass']
        for iface in interfaces:
            res = iface.implementedBy(type)
            if res:
                return True
        return False

    security.declareProtected(permissions.View, 'isTemplateEnabled')

    def isTemplateEnabled(self, type):
        """Checks if an type uses ITemplateMixin.
        """
        return self.typeImplementsInterfaces(type, [ITemplateMixin])

    security.declareProtected(
        permissions.View, 'listTemplateEnabledPortalTypes')

    def listTemplateEnabledPortalTypes(self):
        """Return a list of portal_types with ITemplateMixin
        """
        return self.listPortalTypesWithInterfaces([ITemplateMixin])

    security.declareProtected(
        permissions.View, 'listPortalTypesWithInterfaces')

    def listPortalTypesWithInterfaces(self, ifaces):
        """Returns a list of ftis of which the types implement one of
        the given interfaces.  Only returns AT types.

        Get a list of FTIs of types implementing IReferenceable:
        >>> portal = layer['portal']
        >>> from Products.Archetypes.config import TOOL_NAME
        >>> tool = getToolByName(portal, TOOL_NAME)
        >>> ftis = tool.listPortalTypesWithInterfaces([IReferenceable])

        Sort the type ids and print them:
        >>> type_ids = [fti.getId() for fti in ftis]
        >>> type_ids.sort()
        >>> type_ids
        ['ATBIFolder', 'Collection', 'ComplexType', ...]
        """
        pt = getToolByName(self, 'portal_types')
        value = []
        for data in listTypes():
            klass = data['klass']
            for iface in ifaces:
                if iface.implementedBy(klass):
                    ti = pt.getTypeInfo(data['portal_type'])
                    if ti is not None:
                        value.append(ti)
        return value

    # Type/Schema Management
    security.declareProtected(permissions.View, 'listRegisteredTypes')

    def listRegisteredTypes(self, inProject=False, portalTypes=False):
        """Return the list of sorted types.
        """

        def type_sort(a, b):
            v = cmp(a['package'], b['package'])
            if v != False:
                return v

            c = cmp(a['klass'].__class__.__name__,
                    b['klass'].__class__.__name__)

            if c == False:
                return cmp(a['package'], b['package'])
            return c

        values = listTypes()
        values.sort(type_sort)

        if inProject:
            # portal_type can change (as it does after ATCT-migration), so we
            # need to check against the content_meta_type of each type-info
            ttool = getToolByName(self, 'portal_types')
            types = [ti.Metatype() for ti in ttool.listTypeInfo()]
            if portalTypes:
                values = [v for v in values if v['portal_type'] in types]
            else:
                values = [v for v in values if v['meta_type'] in types]

        return values

    security.declareProtected(permissions.View, 'getTypeSpec')

    def getTypeSpec(self, package, type):
        t = self.lookupType(package, type)
        module = t['klass'].__module__
        klass = t['name']
        return '%s.%s' % (module, klass)

    security.declareProtected(permissions.View, 'listTypes')

    def listTypes(self, package=None, type=None):
        """Just the class.
        """
        if type is None:
            return [t['klass'] for t in listTypes(package)]
        else:
            return [getType(type, package)['klass']]

    security.declareProtected(permissions.View, 'lookupType')

    def lookupType(self, package, type):
        types = self.listRegisteredTypes()
        for t in types:
            if t['package'] != package:
                continue
            if t['meta_type'] == type:
                # We have to return the schema wrapped into the acquisition of
                # something to allow access. Otherwise we will end up with:
                # Your user account is defined outside the context of the object
                # being accessed.
                t['schema'] = ImplicitAcquisitionWrapper(t['schema'], self)
                return t
        return None

    security.declareProtected(permissions.ManagePortal,
                              'manage_installType')

    def manage_installType(self, typeName, package=None,
                           uninstall=None, REQUEST=None):
        """Un/Install a type TTW.
        """
        typesTool = getToolByName(self, 'portal_types')
        try:
            typesTool._delObject(typeName)
        except (ConflictError, KeyboardInterrupt):
            raise
        except:  # XXX bare exception
            pass
        if uninstall is not None:
            if REQUEST:
                return REQUEST.RESPONSE.redirect(self.absolute_url() +
                                                 '/manage_debugForm')
            return

        typeinfo_name = '%s: %s' % (package, typeName)

        # We want to run the process/modify_fti code which might not
        # have been called
        typeDesc = getType(typeName, package)
        process_types([typeDesc], package)
        klass = typeDesc['klass']

        # get the meta type of the FTI from the class, use the default FTI as
        # default
        fti_meta_type = getattr(klass, '_at_fti_meta_type', None)
        if fti_meta_type in (None, 'simple item'):
            fti_meta_type = FactoryTypeInformation.meta_type

        typesTool.manage_addTypeInformation(fti_meta_type,
                                            id=typeName,
                                            typeinfo_name=typeinfo_name)
        t = getattr(typesTool, typeName, None)
        if t:
            t.title = getattr(klass, 'archetype_name',
                              typeDesc['portal_type'])

        # and update the actions as needed
        fixActionsForType(klass, typesTool)

        if REQUEST:
            return REQUEST.RESPONSE.redirect(self.absolute_url() +
                                             '/manage_debugForm')

    security.declarePublic('getSearchWidgets')

    def getSearchWidgets(self, package=None, type=None,
                         context=None, nosort=None):
        """Empty widgets for searching.
        """
        return self.getWidgets(package=package, type=type,
                               context=context, mode='search', nosort=nosort)

    security.declarePublic('getWidgets')

    def getWidgets(self, instance=None,
                   package=None, type=None,
                   context=None, mode='edit',
                   fields=None, schemata=None, nosort=None):
        """Empty widgets for standalone rendering.
        """
        widgets = []
        w_keys = {}
        context = context is not None and context or self
        instances = instance is not None and [instance] or []
        f_names = fields
        if not instances:
            for t in self.listTypes(package, type):
                instance = t('fake_instance')
                instance._at_is_fake_instance = True
                wrapped = instance.__of__(context)
                wrapped.initializeArchetype()
                instances.append(wrapped)
        for instance in instances:
            if schemata is not None:
                schema = instance.Schemata()[schemata].copy()
            else:
                schema = instance.Schema().copy()
            fields = schema.fields()
            if mode == 'search':
                # Include only fields which have an index
                # XXX duplicate fieldnames may break this,
                # as different widgets with the same name
                # on different schemas means only the first
                # one found will be used
                indexes = self.portal_catalog.indexes()
                fields = [f for f in fields
                          if (f.accessor and
                              not f.accessor in w_keys
                              and f.accessor in indexes)]
            if f_names is not None:
                fields = filter(lambda f: f.getName() in f_names, fields)
            for field in fields:
                widget = field.widget
                field_name = field.getName()
                accessor = field.getAccessor(instance)
                if mode == 'search':
                    field.required = False
                    field.addable = False  # for ReferenceField
                    if not isinstance(field.vocabulary, DisplayList):
                        field.vocabulary = field.Vocabulary(instance)
                    if '' not in field.vocabulary.keys():
                        field.vocabulary = DisplayList([('', _(u'at_search_any', default=u'<any>'))]) + \
                            field.vocabulary
                    widget.populate = False
                    field_name = field.accessor
                    # accessor must be a method which doesn't take an argument
                    # this lambda is facking an accessor
                    accessor = lambda: field.getDefault(instance)

                w_keys[field_name] = None
                widgets.append((field_name, WidgetWrapper(
                    field_name=field_name,
                    mode=mode,
                    widget=widget,
                    instance=instance,
                    field=field,
                    accessor=accessor)))
        if mode == 'search' and nosort == None:
            widgets.sort()
        return [widget for name, widget in widgets]

    security.declarePrivate('_rawEnum')

    def _rawEnum(self, callback, *args, **kwargs):
        """Finds all object to check if they are 'referenceable'.
        """
        catalog = getToolByName(self, 'portal_catalog')
        brains = catalog(dict(id=[]))
        for b in brains:
            o = b.getObject()
            if o is not None:
                if IBaseObject.providedBy(o):
                    callback(o, *args, **kwargs)
            else:
                log('no object for brain: %s:%s' % (b, b.getURL()))

    security.declareProtected(permissions.View, 'enum')

    def enum(self, callback, *args, **kwargs):
        catalog = getToolByName(self, UID_CATALOG)
        keys = catalog.uniqueValuesFor('UID')
        for uid in keys:
            o = self.getObject(uid)
            if o:
                callback(o, *args, **kwargs)
            else:
                log('No object for %s' % uid)

    security.declareProtected(permissions.View, 'Content')

    def Content(self):
        """Return a list of all the content ids.
        """
        catalog = getToolByName(self, UID_CATALOG)
        keys = catalog.uniqueValuesFor('UID')
        results = catalog(dict(UID=keys))
        return results

    # Management Forms
    security.declareProtected(permissions.ManagePortal,
                              'manage_doGenerate')

    def manage_doGenerate(self, sids=(), REQUEST=None):
        """(Re)generate types.
        """
        schemas = []
        for sid in sids:
            schemas.append(self.getSchema(sid))

        for s in schemas:
            s.generate()

        if REQUEST:
            return REQUEST.RESPONSE.redirect(self.absolute_url() +
                                             '/manage_workspace')

    security.declareProtected(permissions.ManagePortal,
                              'manage_inspect')

    def manage_inspect(self, UID, REQUEST=None):
        """Dump some things about an object hook in the debugger for now.
        """
        object = self.getObject(UID)
        log("uid: %s, schema: %s" % (object, object.Schema()))

        return REQUEST.RESPONSE.redirect(self.absolute_url() +
                                         '/manage_uids')

    security.declareProtected(permissions.ManagePortal,
                              'manage_reindex')

    def manage_reindex(self, REQUEST=None):
        """Assign UIDs to all basecontent objects.
        """

        def _index(object, archetype_tool):
            archetype_tool.registerContent(object)

        self._rawEnum(_index, self)

        return REQUEST.RESPONSE.redirect(self.absolute_url() +
                                         '/manage_uids')

    security.declareProtected(permissions.ManagePortal, 'index')
    index = manage_reindex

    def _listAllTypes(self):
        """List all types -- either currently known or known to us.
        """
        allTypes = _types.copy()
        allTypes.update(self._types)
        return allTypes.keys()

    security.declareProtected(permissions.ManagePortal,
                              'getChangedSchema')

    def getChangedSchema(self):
        """Returns a list of tuples indicating which schema have changed.

        Tuples have the form (schema, changed).
        """
        list = []
        currentTypes = _types
        ourTypes = self._types
        modified = False
        keys = self._listAllTypes()
        keys.sort()
        for t in keys:
            if t not in ourTypes:
                # Add it
                ourTypes[t] = currentTypes[t]['signature']
                modified = True
                list.append((t, 0))
            elif t not in currentTypes:
                # Huh: what shall we do? We remove it -- this might be wrong!
                del ourTypes[t]
                modified = True
                # We do not add an entry because we cannot update
                # these objects (having no longer type information for them)
            else:
                list.append((t, ourTypes[t] != currentTypes[t]['signature']))
        if modified:
            self._p_changed = True
        return list

    security.declareProtected(permissions.ManagePortal,
                              'manage_updateSchema')

    def manage_updateSchema(self, REQUEST=None, update_all=None,
                            remove_instance_schemas=None):
        """Make sure all objects' schema are up to date.
        """
        out = StringIO()
        print >> out, 'Updating schema...'

        update_types = []
        if REQUEST is None:
            # DM (avoid persistency bug): avoid code duplication
            update_types = [ti[0] for ti in self.getChangedSchema() if ti[1]]
        else:
            # DM (avoid persistency bug):
            for t in self._listAllTypes():
                if REQUEST.form.get(t, False):
                    update_types.append(t)
            update_all = REQUEST.form.get('update_all', False)
            remove_instance_schemas = REQUEST.form.get(
                'remove_instance_schemas', False)

        # XXX: Enter this block only when there are types to update!
        if update_types:
            # Use the catalog's ZopeFindAndApply method to walk through
            # all objects in the portal.  This works much better than
            # relying on the catalog to find objects, because an object
            # may be uncatalogable because of its schema, and then you
            # can't update it if you require that it be in the catalog.
            catalog = getToolByName(self, 'portal_catalog')
            portal = getToolByName(self, 'portal_url').getPortalObject()
            meta_types = [_types[t]['meta_type'] for t in update_types]
            if remove_instance_schemas:
                func_update_changed = self._removeSchemaAndUpdateChangedObject
                func_update_all = self._removeSchemaAndUpdateObject
            else:
                func_update_changed = self._updateChangedObject
                func_update_all = self._updateObject
            if update_all:
                catalog.ZopeFindAndApply(portal, obj_metatypes=meta_types,
                                         search_sub=True, apply_func=func_update_all)
            else:
                catalog.ZopeFindAndApply(portal, obj_metatypes=meta_types,
                                         search_sub=True, apply_func=func_update_changed)
            for t in update_types:
                self._types[t] = _types[t]['signature']
            self._p_changed = True

        print >> out, 'Done.'
        return out.getvalue()

    # A counter to ensure that in a given interval a subtransaction
    # commit is done.
    subtransactioncounter = 0

    def _updateObject(self, o, path, remove_instance_schemas=None):
        o._updateSchema(remove_instance_schemas=remove_instance_schemas)
        # Subtransactions to avoid eating up RAM when used inside a
        # 'ZopeFindAndApply' like in manage_updateSchema
        self.subtransactioncounter += 1
        # Only every 250 objects a sub-commit, otherwise it eats up all
        # diskspace
        if not self.subtransactioncounter % 250:
            transaction.savepoint(optimistic=True)

    def _updateChangedObject(self, o, path):
        if not o._isSchemaCurrent():
            self._updateObject(o, path)

    def _removeSchemaAndUpdateObject(self, o, path):
        self._updateObject(o, path, remove_instance_schemas=True)

    def _removeSchemaAndUpdateChangedObject(self, o, path):
        if not o._isSchemaCurrent():
            self._removeSchemaAndUpdateObject(o, path)

    security.declareProtected(permissions.ManagePortal,
                              'manage_updateSchema')

    def manage_migrate(self, REQUEST=None):
        """Run Extensions.migrations.migrate.
        """
        from Products.Archetypes.Extensions.migrations import migrate
        out = migrate(self)
        self.manage_updateSchema()
        return out

    # Catalog management
    security.declareProtected(permissions.View,
                              'listCatalogs')

    def listCatalogs(self):
        """Show the catalog mapping.
        """
        return self.catalog_map

    security.declareProtected(permissions.ManagePortal,
                              'manage_updateCatalogs')

    def manage_updateCatalogs(self, REQUEST=None):
        """Set the catalog map for meta_type to include the list
        catalog_names.
        """
        prefix = 'catalog_names_'
        for key in REQUEST.form.keys():
            if key.startswith(prefix):
                k = key[len(prefix):]
                v = REQUEST.form.get(key)
                self.setCatalogsByType(k, v)

        return REQUEST.RESPONSE.redirect(self.absolute_url() +
                                         '/manage_catalogs')

    security.declareProtected(permissions.ManagePortal,
                              'setCatalogsByType')

    def setCatalogsByType(self, portal_type, catalogList):
        """ associate catalogList with meta_type. (unfortunally not portal_type).

            catalogList is a list of strings with the ids of the catalogs.
            Each catalog is has to be a tool, means unique in site root.
        """
        self.catalog_map[portal_type] = catalogList

    security.declareProtected(permissions.View, 'getCatalogsByType')

    def getCatalogsByType(self, portal_type):
        """Return the catalog objects assoicated with a given type.
        """
        catalogs = []
        catalog_map = getattr(self, 'catalog_map', None)
        if catalog_map is not None:
            names = self.catalog_map.get(portal_type, ['portal_catalog'])
        else:
            names = ['portal_catalog']
        portal = getToolByName(self, 'portal_url').getPortalObject()
        for name in names:
            try:
                catalogs.append(getToolByName(portal, name))
            except (ConflictError, KeyboardInterrupt):
                raise
            except Exception, E:
                log('No tool %s' % name, E)
                pass
        return catalogs
Beispiel #58
0
class MembershipTool(UniqueObject, Folder):

    """ This tool accesses member data through an acl_users object.

    It can be replaced with something that accesses member data in a
    different way.
    """

    implements(IMembershipTool)

    id = 'portal_membership'
    meta_type = 'CMF Membership Tool'
    memberareaCreationFlag = 1

    security = ClassSecurityInfo()

    manage_options = (
        ({'label': 'Configuration', 'action': 'manage_mapRoles'},
         {'label': 'Overview', 'action': 'manage_overview'}) +
        Folder.manage_options)

    #
    #   ZMI methods
    #
    security.declareProtected(ManagePortal, 'manage_overview')
    manage_overview = DTMLFile('explainMembershipTool', _dtmldir)

    #
    #   'portal_membership' interface methods
    #
    security.declareProtected(ManagePortal, 'manage_mapRoles')
    manage_mapRoles = DTMLFile('membershipRolemapping', _dtmldir)

    security.declareProtected(SetOwnPassword, 'setPassword')
    @postonly
    def setPassword(self, password, domains=None, REQUEST=None):
        '''Allows the authenticated member to set his/her own password.
        '''
        if not self.isAnonymousUser():
            member = self.getAuthenticatedMember()
            rtool = queryUtility(IRegistrationTool)
            if rtool is not None:
                failMessage = rtool.testPasswordValidity(password)
                if failMessage is not None:
                    raise BadRequest(failMessage)
            member.setSecurityProfile(password=password, domains=domains)
        else:
            raise BadRequest('Not logged in.')

    security.declarePublic('getAuthenticatedMember')
    def getAuthenticatedMember(self):
        '''
        Returns the currently authenticated member object
        or the Anonymous User.  Never returns None.
        '''
        u = getSecurityManager().getUser()
        if u is None:
            u = nobody
        return self.wrapUser(u)

    security.declarePrivate('wrapUser')
    def wrapUser(self, u, wrap_anon=0):
        """ Set up the correct acquisition wrappers for a user object.

        Provides an opportunity for a portal_memberdata tool to retrieve and
        store member data independently of the user object.
        """
        b = getattr(u, 'aq_base', None)
        if b is None:
            # u isn't wrapped at all.  Wrap it in self.acl_users.
            b = u
            u = u.__of__(self.acl_users)
        if (b is nobody and not wrap_anon) or hasattr(b, 'getMemberId'):
            # This user is either not recognized by acl_users or it is
            # already registered with something that implements the
            # member data tool at least partially.
            return u

        # Apply any role mapping if we have it
        if hasattr(self, 'role_map'):
            for portal_role in self.role_map.keys():
                if (self.role_map.get(portal_role) in u.roles and
                        portal_role not in u.roles):
                    u.roles.append(portal_role)

        mdtool = queryUtility(IMemberDataTool)
        if mdtool is not None:
            try:
                u = mdtool.wrapUser(u)
            except ConflictError:
                raise
            except:
                logger.exception("Error during wrapUser")
        return u

    security.declareProtected(ManagePortal, 'getPortalRoles')
    def getPortalRoles(self):
        """
        Return all local roles defined by the portal itself,
        which means roles that are useful and understood
        by the portal object
        """
        parent = self.aq_inner.aq_parent
        roles = list(parent.userdefined_roles())

        # This is *not* a local role in the portal but used by it
        roles.append('Manager')
        roles.append('Owner')

        return roles

    security.declareProtected(ManagePortal, 'setRoleMapping')
    @postonly
    def setRoleMapping(self, portal_role, userfolder_role, REQUEST=None):
        """
        set the mapping of roles between roles understood by
        the portal and roles coming from outside user sources
        """
        if not hasattr(self, 'role_map'):
            self.role_map = PersistentMapping()

        if len(userfolder_role) < 1:
            del self.role_map[portal_role]
        else:
            self.role_map[portal_role] = userfolder_role

        return MessageDialog(
               title='Mapping updated',
               message='The Role mappings have been updated',
               action='manage_mapRoles')

    security.declareProtected(ManagePortal, 'getMappedRole')
    def getMappedRole(self, portal_role):
        """
        returns a role name if the portal role is mapped to
        something else or an empty string if it is not
        """
        if hasattr(self, 'role_map'):
            return self.role_map.get(portal_role, '')
        else:
            return ''

    security.declarePublic('getMembersFolder')
    def getMembersFolder(self):
        """ Get the members folder object.
        """
        parent = aq_parent(aq_inner(self))
        members_folder = getattr(parent, 'Members', None)
        if members_folder is None:
            return None
        request_container = RequestContainer(REQUEST=getRequest())
        return members_folder.__of__(request_container)

    security.declareProtected(ManagePortal, 'getMemberareaCreationFlag')
    def getMemberareaCreationFlag(self):
        """
        Returns the flag indicating whether the membership tool
        will create a member area if an authenticated user from
        an underlying user folder logs in first without going
        through the join process
        """
        return self.memberareaCreationFlag

    security.declareProtected(ManagePortal, 'setMemberareaCreationFlag')
    def setMemberareaCreationFlag(self):
        """
        sets the flag indicating whether the membership tool
        will create a member area if an authenticated user from
        an underlying user folder logs in first without going
        through the join process
        """
        if not hasattr(self, 'memberareaCreationFlag'):
            self.memberareaCreationFlag = 0

        if self.memberareaCreationFlag == 0:
            self.memberareaCreationFlag = 1
        else:
            self.memberareaCreationFlag = 0

        return MessageDialog(
               title='Member area creation flag changed',
               message='Member area creation flag has been updated',
               action='manage_mapRoles')

    security.declarePublic('createMemberArea')
    def createMemberArea(self, member_id=''):
        """ Create a member area for 'member_id' or authenticated user.
        """
        if not self.getMemberareaCreationFlag():
            return None
        members = self.getMembersFolder()
        if members is None:
            return None
        if self.isAnonymousUser():
            return None
        if member_id:
            if not self.isMemberAccessAllowed(member_id):
                return None
            member = self.getMemberById(member_id)
            if member is None:
                return None
        else:
            member = self.getAuthenticatedMember()
            member_id = member.getId()
        if hasattr(aq_base(members), member_id):
            return None
        else:
            f_title = "%s's Home" % member_id
            members.manage_addPortalFolder(id=member_id, title=f_title)
            f = getattr(members, member_id)

            f.manage_permission(View,
                                ['Owner', 'Manager', 'Reviewer'], 0)
            f.manage_permission(AccessContentsInformation,
                                ['Owner', 'Manager', 'Reviewer'], 0)

            # Grant Ownership and Owner role to Member
            f.changeOwnership(member)
            f.__ac_local_roles__ = None
            f.manage_setLocalRoles(member_id, ['Owner'])
        return f

    security.declarePublic('createMemberarea')
    createMemberarea = createMemberArea

    security.declareProtected(ManageUsers, 'deleteMemberArea')
    @postonly
    def deleteMemberArea(self, member_id, REQUEST=None):
        """ Delete member area of member specified by member_id.
        """
        members = self.getMembersFolder()
        if not members:
            return 0
        if hasattr(aq_base(members), member_id):
            members.manage_delObjects(member_id)
            return 1
        else:
            return 0

    security.declarePublic('isAnonymousUser')
    def isAnonymousUser(self):
        '''
        Returns 1 if the user is not logged in.
        '''
        u = getSecurityManager().getUser()
        if u is None or u.getUserName() == 'Anonymous User':
            return 1
        return 0

    security.declarePublic('checkPermission')
    def checkPermission(self, permissionName, object, subobjectName=None):
        '''
        Checks whether the current user has the given permission on
        the given object or subobject.
        '''
        if subobjectName is not None:
            object = getattr(object, subobjectName)
        return _checkPermission(permissionName, object)

    security.declareProtected(ManageUsers, 'isMemberAccessAllowed')
    def isMemberAccessAllowed(self, member_id):
        """Check if the authenticated user is this member or an user manager.
        """
        sm = getSecurityManager()
        user = sm.getUser()
        if user is None:
            return False
        if member_id == user.getId():
            return True
        return sm.checkPermission(ManageUsers, self)

    security.declarePublic('credentialsChanged')
    def credentialsChanged(self, password, REQUEST=None):
        '''
        Notifies the authentication mechanism that this user has changed
        passwords.  This can be used to update the authentication cookie.
        Note that this call should *not* cause any change at all to user
        databases.
        '''
        if not self.isAnonymousUser():
            user = getSecurityManager().getUser()
            name = user.getUserName()
            # this really does need to be the user name, and not the user id,
            # because we're dealing with authentication credentials
            cctool = queryUtility(ICookieCrumbler)
            if cctool is not None:
                cctool.credentialsChanged(user, name, password, REQUEST)

    security.declareProtected(ManageUsers, 'getMemberById')
    def getMemberById(self, id):
        '''
        Returns the given member.
        '''
        user = self._huntUser(id, self)
        if user is not None:
            user = self.wrapUser(user)
        return user

    def _huntUserFolder(self, member_id, context):
        """Find userfolder containing user in the hierarchy
           starting from context
        """
        uf = context.acl_users
        while uf is not None:
            user = uf.getUserById(member_id)
            if user is not None:
                return uf
            container = aq_parent(aq_inner(uf))
            parent = aq_parent(aq_inner(container))
            uf = getattr(parent, 'acl_users', None)
        return None

    def _huntUser(self, member_id, context):
        """Find user in the hierarchy of userfolders
           starting from context
        """
        uf = self._huntUserFolder(member_id, context)
        if uf is not None:
            return uf.getUserById(member_id).__of__(uf)

    def __getPUS(self):
        """ Retrieve the nearest user folder
        """
        warn('__getPUS is deprecated and will be removed in CMF 2.4, '
             'please acquire "acl_users" instead.', DeprecationWarning,
             stacklevel=2)
        return self.acl_users

    security.declareProtected(ManageUsers, 'listMemberIds')
    def listMemberIds(self):
        '''Lists the ids of all members.  This may eventually be
        replaced with a set of methods for querying pieces of the
        list rather than the entire list at once.
        '''
        user_folder = self.acl_users
        return [ x.getId() for x in user_folder.getUsers() ]

    security.declareProtected(ManageUsers, 'listMembers')
    def listMembers(self):
        '''Gets the list of all members.
        '''
        return map(self.wrapUser, self.acl_users.getUsers())

    security.declareProtected(ListPortalMembers, 'searchMembers')
    def searchMembers(self, search_param, search_term):
        """ Search the membership """
        mdtool = queryUtility(IMemberDataTool)
        if mdtool is not None:
            return mdtool.searchMemberData(search_param, search_term)
        return None

    security.declareProtected(View, 'getCandidateLocalRoles')
    def getCandidateLocalRoles(self, obj):
        """ What local roles can I assign?
        """
        member = self.getAuthenticatedMember()
        member_roles = member.getRolesInContext(obj)
        if _checkPermission(ManageUsers, obj):
            local_roles = self.getPortalRoles()
            if 'Manager' not in member_roles:
                local_roles.remove('Manager')
        else:
            local_roles = [ role for role in member_roles
                            if role not in ('Member', 'Authenticated') ]
        local_roles.sort()
        return tuple(local_roles)

    security.declareProtected(View, 'setLocalRoles')
    @postonly
    def setLocalRoles(self, obj, member_ids, member_role, reindex=1,
                      REQUEST=None):
        """ Add local roles on an item.
        """
        if (_checkPermission(ChangeLocalRoles, obj)
            and member_role in self.getCandidateLocalRoles(obj)):
            for member_id in member_ids:
                roles = list(obj.get_local_roles_for_userid(userid=member_id))

                if member_role not in roles:
                    roles.append(member_role)
                    obj.manage_setLocalRoles(member_id, roles)

        if reindex and hasattr(aq_base(obj), 'reindexObjectSecurity'):
            obj.reindexObjectSecurity()

    security.declareProtected(View, 'deleteLocalRoles')
    @postonly
    def deleteLocalRoles(self, obj, member_ids, reindex=1, recursive=0,
                         REQUEST=None):
        """ Delete local roles of specified members.
        """
        if _checkPermission(ChangeLocalRoles, obj):
            for member_id in member_ids:
                if obj.get_local_roles_for_userid(userid=member_id):
                    obj.manage_delLocalRoles(userids=member_ids)
                    break

        if recursive and hasattr(aq_base(obj), 'contentValues'):
            for subobj in obj.contentValues():
                self.deleteLocalRoles(subobj, member_ids, 0, 1)

        if reindex and hasattr(aq_base(obj), 'reindexObjectSecurity'):
            # reindexObjectSecurity is always recursive
            obj.reindexObjectSecurity()

    security.declarePrivate('addMember')
    def addMember(self, id, password, roles, domains, properties=None):
        '''Adds a new member to the user folder.  Security checks will have
        already been performed.  Called by portal_registration.
        '''
        self.acl_users._doAddUser(id, password, roles, domains)

        if properties is not None:
            member = self.getMemberById(id)
            member.setMemberProperties(properties)

    security.declareProtected(ManageUsers, 'deleteMembers')
    @postonly
    def deleteMembers(self, member_ids, delete_memberareas=1,
                      delete_localroles=1, REQUEST=None):
        """ Delete members specified by member_ids.
        """
        # Delete members in acl_users.
        acl_users = self.acl_users
        if _checkPermission(ManageUsers, acl_users):
            if isinstance(member_ids, basestring):
                member_ids = (member_ids,)
            member_ids = list(member_ids)
            for member_id in member_ids[:]:
                if not acl_users.getUserById(member_id, None):
                    member_ids.remove(member_id)
            try:
                acl_users.userFolderDelUsers(member_ids)
            except (AttributeError, NotImplementedError):
                raise NotImplementedError('The underlying User Folder '
                                         'doesn\'t support deleting members.')
        else:
            raise AccessControl_Unauthorized('You need the \'Manage users\' '
                                 'permission for the underlying User Folder.')

        # Delete member data in portal_memberdata.
        mdtool = queryUtility(IMemberDataTool)
        if mdtool is not None:
            for member_id in member_ids:
                mdtool.deleteMemberData(member_id)

        # Delete members' home folders including all content items.
        if delete_memberareas:
            for member_id in member_ids:
                self.deleteMemberArea(member_id)

        # Delete members' local roles.
        if delete_localroles:
            self.deleteLocalRoles(getUtility(ISiteRoot), member_ids,
                                  reindex=1, recursive=1)

        return tuple(member_ids)

    security.declarePublic('getHomeFolder')
    def getHomeFolder(self, id=None, verifyPermission=0):
        """Returns a member's home folder object or None.
        Set verifyPermission to 1 to return None when the user
        doesn't have the View permission on the folder.
        """
        return None

    security.declarePublic('getHomeUrl')
    def getHomeUrl(self, id=None, verifyPermission=0):
        """Returns the URL to a member's home folder or None.
        Set verifyPermission to 1 to return None when the user
        doesn't have the View permission on the folder.
        """
        return None