Exemple #1
0
 def test_get_all_suffixes(self):
     self.assertEqual(get_all_suffixes(self.uid),
                      [u'observer', u'director'])
     dep2_uid = self.dep2.UID()
     self.assertEqual(get_all_suffixes(dep2_uid),
                      [u'observer', u'director'])
     self.assertEqual(get_all_suffixes(), [u'observer', u'director'])
Exemple #2
0
 def test_get_all_suffixes_fct_orgs(self):
     dep2_uid = self.dep2.UID()
     self.assertEqual(get_all_suffixes(dep2_uid),
                      [u'observer', u'director'])
     functions = get_registry_functions()
     functions[0]['fct_orgs'] = [self.uid]
     set_registry_functions(functions)
     self.assertEqual(get_all_suffixes(dep2_uid), [u'director'])
Exemple #3
0
 def test_get_all_suffixes_only_enabled(self):
     dep2_uid = self.dep2.UID()
     self.assertEqual(get_all_suffixes(dep2_uid, only_enabled=True),
                      [u'observer', u'director'])
     functions = get_registry_functions()
     functions[0]['enabled'] = False
     set_registry_functions(functions)
     self.assertEqual(get_all_suffixes(dep2_uid, only_enabled=True),
                      [u'director'])
     self.assertEqual(get_all_suffixes(dep2_uid, only_enabled=False),
                      [u'observer', u'director'])
def group_deleted(event):
    """
        Raises exception if group cannot be deleted
    """
    group = event.principal
    portal = api.portal.get()
    request = portal.REQUEST

    parts = group.split('_')
    if len(parts) == 1:
        return
    org_uid = parts[0]
    group_suffix = '_'.join(parts[1:])
    if org_uid in get_registry_organizations(
    ) and group_suffix in get_all_suffixes(org_uid):
        orga = api.content.find(UID=org_uid)[0].getObject()
        api.portal.show_message(message=_(
            "You cannot delete the group '${group}', linked to used organization "
            "'${orga}'.",
            mapping={
                'group': group,
                'orga': safe_unicode(orga.Title())
            }),
                                request=request,
                                type='error')
        raise Redirect(request.get('ACTUAL_URL'))
Exemple #5
0
 def __call__(self, context):
     all_suffixes = get_all_suffixes()
     terms = []
     for group in api.group.get_groups():
         if group.id in ('Administrators', 'Reviewers', 'Site Administrators', 'AuthenticatedUsers'):
             continue
         parts = group.id.split('_')
         if len(parts) > 1:
             group_suffix = '_'.join(parts[1:])
             if group_suffix in all_suffixes:
                 continue
         terms.append(SimpleTerm(group.id, title=group.getProperty('title') or group.id))
     return SimpleVocabulary(terms)
Exemple #6
0
    def addUsers(self, org_descriptors):
        '''Creates Plone users and add it to linked Plone groups.'''
        plone_utils = self.portal.plone_utils
        # if we are in dev, we use DEFAULT_USER_PASSWORD, else we will generate a
        # password that is compliant with the current password policy...
        if is_develop_environment():
            password = DEFAULT_USER_PASSWORD
        else:
            password = generate_password()
        msg = "The password used for added users is %s" % (
            password or DEFAULT_USER_PASSWORD)
        logger.info(msg)
        # add a portal_message so admin adding the Plone site knows password
        plone_utils.addPortalMessage(msg, 'warning')

        member_tool = api.portal.get_tool('portal_membership')

        own_org = get_own_organization()
        plonegroup_org_uids = get_registry_organizations()
        for org_descr in org_descriptors:
            if org_descr.parent_path:
                # find parent organization following parent path from container
                container = own_org.restrictedTraverse(org_descr.parent_path)
            else:
                container = own_org
            org = container.get(org_descr.id)
            # Create users
            for userDescr in org_descr.getUsers():
                # if we defined a generated password here above, we use it
                # either we use the password provided in the applied profile
                if password:
                    userDescr.password = password
                self.addUser(userDescr)
            # Add users in the correct Plone groups.
            org_uid = org.UID()
            if org_uid in plonegroup_org_uids:
                for suffix in get_all_suffixes(org_uid):
                    plone_group = get_plone_group(org_uid, suffix)
                    group_members = plone_group.getMemberIds()
                    # protect in case we have suffixes only for some groups
                    for userDescr in getattr(org_descr, suffix, []):
                        if userDescr.id not in group_members:
                            api.group.add_user(group=plone_group,
                                               username=userDescr.id)
                            if userDescr.create_member_area:
                                member_tool.createMemberArea(userDescr.id)
def group_deleted(event):
    """
        Raises exception if group cannot be deleted
    """
    group = event.principal
    portal = api.portal.get()
    request = portal.REQUEST

    parts = group.split('_')
    if len(parts) == 1:
        return
    group_suffix = '_'.join(parts[1:])
    registry = getUtility(IRegistry)
    if parts[0] in registry[ORGANIZATIONS_REGISTRY] and group_suffix in get_all_suffixes(parts[0]):
        orga = api.content.find(UID=parts[0])[0].getObject()
        api.portal.show_message(message=_("You cannot delete the group '${group}', linked to used organization "
                                          "'${orga}'.", mapping={'group': group, 'orga': safe_unicode(orga.Title())}),
                                request=request, type='error')
        raise Redirect(request.get('ACTUAL_URL'))
def selectedOrganizationsPloneGroupsVocabulary(functions=[], group_title=True):
    """
        Returns a vocabulary of selected organizations corresponding plone groups
    """
    terms = []
    # if no function given, use all functions
    functions = functions or get_all_suffixes()
    for orga_uid in get_registry_organizations():
        for fct_id in functions:
            group_id = "%s_%s" % (orga_uid, fct_id)
            group = api.group.get(groupname=group_id)
            if group is not None:
                if group_title:
                    title = group.getProperty('title')
                else:
                    title = uuidToObject(orga_uid).get_full_title(
                        separator=' - ', first_index=1)
                terms.append(SimpleTerm(group_id, token=group_id, title=title))
    return SimpleVocabulary(terms)
Exemple #9
0
 def _display_available_items_to(self):
     """Check if current user profile is selected in MeetingConfig.displayAvailableItemsTo."""
     displayAvailableItemsTo = self.cfg.getDisplayAvailableItemsTo()
     suffixes = []
     groups = []
     res = False
     cfgId = self.cfg.getId()
     for value in displayAvailableItemsTo:
         if value == 'app_users':
             suffixes = get_all_suffixes()
         elif value.startswith(POWEROBSERVERPREFIX):
             groups.append(
                 get_plone_group_id(cfgId,
                                    value.split(POWEROBSERVERPREFIX)[1]))
     if suffixes:
         res = self.tool.userIsAmong(suffixes)
     if not res and groups:
         res = bool(
             set(groups).intersection(
                 self.tool.get_plone_groups_for_user()))
     return res
    def renderCell(self, item):
        """ """
        plonegroup_organizations = get_registry_organizations()
        org_uid = item.UID
        if org_uid not in plonegroup_organizations:
            return "-"

        suffixes = get_all_suffixes(org_uid)
        group_ids = [
            get_plone_group_id(org_uid, suffix) for suffix in suffixes
        ]
        url_group_ids = '&group_ids='.join(group_ids)
        # use _ for i18ndude machinery
        details_msg = _('Details')
        details_msg = translate(details_msg, context=self.request)
        res = u"<div id=\"group-users\" class=\"collapsible\" onclick=\"toggleDetails(" \
            u"'collapsible-group-users_{0}', toggle_parent_active=false, parent_tag=null, " \
            u"load_view='@@display-group-users?group_ids={1}&short:boolean={2}', base_url='{3}');\"> {4}</div>" \
            u"<div id=\"collapsible-group-users_{0}\" class=\"collapsible-content\" style=\"display: none;\">" \
            u"<div class=\"collapsible-inner-content\">" \
            u"<img src=\"{3}/spinner_small.gif\" /></div></div>".format(
                org_uid, url_group_ids, self.short, self.table.portal_url, details_msg)
        return res
    def validateSettings(data):
        if not data.organizations:
            raise Invalid(_(u"You must choose at least one organization !"))
        if len(data.organizations) == 1 and data.organizations[0] is None:
            raise Invalid(
                _(u"You must correct the organization error first !"))
        if not data.functions:
            raise Invalid(_(u"You must define at least one function !"))

        # only able to delete a function (suffix) if every linked Plone groups are empty
        stored_suffixes = get_all_suffixes()
        saved_suffixes = [func['fct_id'] for func in data.functions]
        removed_suffixes = list(set(stored_suffixes) - set(saved_suffixes))
        for removed_suffix in removed_suffixes:
            # check that every organizations including not selected
            # linked suffixed Plone group is empty
            for org_uid in get_organizations(only_selected=False,
                                             the_objects=False):
                plone_group_id = get_plone_group_id(org_uid, removed_suffix)
                plone_group = api.group.get(plone_group_id)
                if plone_group and plone_group.getMemberIds():
                    raise Invalid(
                        _(u"can_not_remove_function_every_plone_groups_not_empty",
                          mapping={
                              'removed_function': removed_suffix,
                              'plone_group_id': plone_group_id
                          }))

        # only able to select orgs for an existing function (suffix) if
        # every linked Plone groups of not selected orgs are empty
        stored_functions = get_registry_functions()
        old_functions = {
            dic['fct_id']: {
                'fct_title': dic['fct_title'],
                'fct_orgs': dic['fct_orgs'],
                'enabled': dic['enabled']
            }
            for dic in stored_functions
        }
        new_functions = {
            dic['fct_id']: {
                'fct_title': dic['fct_title'],
                'fct_orgs': dic['fct_orgs'],
                'enabled': dic['enabled']
            }
            for dic in data.functions
        }
        for new_function, new_function_infos in new_functions.items():
            if new_function_infos['fct_orgs'] and \
               old_functions[new_function]['fct_orgs'] != new_function_infos['fct_orgs']:
                # check that Plone group is empty for not selected fct_orgs
                for org_uid in get_organizations(only_selected=False,
                                                 the_objects=False):
                    if org_uid in new_function_infos['fct_orgs']:
                        continue
                    plone_group_id = get_plone_group_id(org_uid, new_function)
                    plone_group = api.group.get(plone_group_id)
                    # use getGroupMembers to ignore '<not found>' users
                    if plone_group and plone_group.getGroupMembers():
                        raise Invalid(
                            _(u"can_not_select_function_orgs_every_other_plone_groups_not_empty",
                              mapping={
                                  'function': new_function,
                                  'plone_group_id': plone_group_id
                              }))
            elif new_function_infos['enabled'] is False:
                # check that Plone groups are all empty
                for org_uid in get_organizations(only_selected=False,
                                                 the_objects=False):
                    plone_group_id = get_plone_group_id(org_uid, new_function)
                    plone_group = api.group.get(plone_group_id)
                    # use getGroupMembers to ignore '<not found>' users
                    if plone_group and plone_group.getGroupMembers():
                        raise Invalid(
                            _(u"can_not_disable_suffix_plone_groups_not_empty",
                              mapping={
                                  'disabled_function': new_function,
                                  'plone_group_id': plone_group_id
                              }))
 def _get_suffixes(self, group_id):
     """Make it possible to ignore some suffixes for p_group_id."""
     suffixes = get_all_suffixes(group_id)
     return suffixes
Exemple #13
0
    def validate(self, value):
        # check that if a suffix is removed, it is not used in MeetingConfig or MeetingItems
        stored_suffixes = get_all_suffixes(only_enabled=True)
        # get removed suffixes...
        saved_suffixes = [func['fct_id'] for func in value]
        saved_enabled_suffixes = [
            func['fct_id'] for func in value if func['enabled']
        ]
        removed_suffixes = list(
            set(stored_suffixes) - set(saved_enabled_suffixes))
        really_removed_suffixes = list(
            set(stored_suffixes) - set(saved_suffixes))
        org_uids = get_organizations(only_selected=False, the_objects=False)
        removed_plonegroups = [
            get_plone_group_id(org_uid, removed_suffix) for org_uid in org_uids
            for removed_suffix in removed_suffixes
        ]
        # ... and new defined fct_orgs as it will remove some suffixed groups
        stored_functions = get_registry_functions()
        old_functions = {
            dic['fct_id']: {
                'fct_title': dic['fct_title'],
                'fct_orgs': dic['fct_orgs'],
                'enabled': dic['enabled']
            }
            for dic in stored_functions
        }
        new_functions = {
            dic['fct_id']: {
                'fct_title': dic['fct_title'],
                'fct_orgs': dic['fct_orgs'],
                'enabled': dic['enabled']
            }
            for dic in value
        }
        for new_function, new_function_infos in new_functions.items():
            if new_function_infos['fct_orgs'] and \
               old_functions[new_function]['fct_orgs'] != new_function_infos['fct_orgs']:
                # check that Plone group is empty for not selected fct_orgs
                for org_uid in org_uids:
                    if org_uid in new_function_infos['fct_orgs']:
                        continue
                    removed_plonegroups.append(
                        get_plone_group_id(org_uid, new_function))
            elif new_function_infos['enabled'] is False:
                # check that Plone groups are all empty
                for org_uid in org_uids:
                    removed_plonegroups.append(
                        get_plone_group_id(org_uid, new_function))

        # check that plonegroups and suffixes not used in MeetingConfigs
        removed_plonegroups = set(removed_plonegroups)
        tool = api.portal.get_tool('portal_plonemeeting')
        # advisers
        advisers_removed_plonegroups = [
            REAL_ORG_UID_PATTERN.format(removed_plonegroup_id.split('_')[0])
            for removed_plonegroup_id in removed_plonegroups
            if removed_plonegroup_id.endswith('_advisers')
        ]
        for cfg in tool.objectValues('MeetingConfig'):
            msg = _("can_not_delete_plone_group_meetingconfig",
                    mapping={'cfg_title': safe_unicode(cfg.Title())})
            # copyGroups
            if removed_plonegroups.intersection(cfg.getSelectableCopyGroups()):
                raise Invalid(msg)
            # advisers (selectableAdvisers/selectableAdviserUsers)
            if set(advisers_removed_plonegroups).intersection(cfg.getSelectableAdvisers()) or \
               set(advisers_removed_plonegroups).intersection(cfg.getSelectableAdviserUsers()):
                raise Invalid(msg)
            # suffixes, values are like 'suffix_proposing_group_level1reviewers'
            composed_values_attributes = [
                'itemAnnexConfidentialVisibleFor',
                'adviceAnnexConfidentialVisibleFor',
                'meetingAnnexConfidentialVisibleFor',
                'itemInternalNotesEditableBy'
            ]
            for composed_values_attr in composed_values_attributes:
                values = cfg.getField(composed_values_attr).getAccessor(cfg)()
                values = [
                    v for v in values for r in removed_suffixes if r in v
                ]
                if values:
                    raise Invalid(msg)
            # itemWFValidationLevels, may be disabled if validation level also disabled
            # but not removed
            item_enabled_val_suffixes = get_item_validation_wf_suffixes(cfg)
            if set(really_removed_suffixes).intersection(
                    item_enabled_val_suffixes):
                raise Invalid(msg)
            all_item_val_suffixes = get_item_validation_wf_suffixes(
                cfg, only_enabled=False)
            if set(removed_suffixes).intersection(all_item_val_suffixes):
                raise Invalid(msg)
        # check that plone_group not used in MeetingItems
        # need to be performant or may kill the instance when several items exist
        if removed_plonegroups:
            catalog = api.portal.get_tool('portal_catalog')
            # copy_groups
            brains = catalog.unrestrictedSearchResults(
                meta_type="MeetingItem",
                getCopyGroups=tuple(removed_plonegroups))
            if not brains:
                brains = catalog.unrestrictedSearchResults(
                    meta_type="MeetingItem",
                    indexAdvisers=tuple(advisers_removed_plonegroups))
            for brain in brains:
                item = brain.getObject()
                if item.isDefinedInTool():
                    msgid = "can_not_delete_plone_group_config_meetingitem"
                else:
                    msgid = "can_not_delete_plone_group_meetingitem"
                msg = _(msgid, mapping={'item_url': item.absolute_url()})
                raise Invalid(msg)
Exemple #14
0
    def _setupPoliceGroup(self):
        '''Configure police group.
           - create 'bourgmestre' group as in charge of police groups;
           - create police/police_compta groups;
           - add 'pmManager' to the _creators group;
           - add some default categories.'''
        # due to complex setup to manage college and council,
        # sometimes this method is called twice...
        if org_id_to_uid(POLICE_GROUP_PREFIX, raise_on_error=False):
            return

        self.changeUser('siteadmin')
        context = self.portal.portal_setup._getImportContext('Products.MeetingCharleroi:testing')
        initializer = ToolInitializer(context, PROJECTNAME)
        # create bourgmestre first as it is a group in charge of police orgs
        orgs, active_orgs, savedOrgsData = initializer.addOrgs([charleroi_import_data.bourg_grp])
        bourg_grp = orgs[0]
        for org in orgs:
            org_uid = org.UID()
            self._select_organization(org_uid)

        # groups_in_charge are organziation ids, we need organization uids
        police_grp = deepcopy(charleroi_import_data.police_grp)
        police_grp.groups_in_charge = [org_id_to_uid(group_in_charge_id)
                                       for group_in_charge_id in police_grp.groups_in_charge]
        police_compta_grp = deepcopy(charleroi_import_data.police_compta_grp)
        police_compta_grp.groups_in_charge = [org_id_to_uid(group_in_charge_id)
                                              for group_in_charge_id in police_compta_grp.groups_in_charge]
        org_descriptors = (police_grp, police_compta_grp)
        orgs, active_orgs, savedOrgsData = initializer.addOrgs(org_descriptors, defer_data=False)
        for org in orgs:
            org_uid = org.UID()
            self._select_organization(org_uid)

        police = orgs[0]
        police_compta = orgs[1]
        gic1 = self.create('organization', id='groupincharge1', title="Group in charge 1", acronym='GIC1')
        gic1_uid = gic1.UID()
        self._select_organization(gic1.UID())
        gic2 = self.create('organization', id='groupincharge2', title="Group in charge 2", acronym='GIC2')
        gic2_uid = gic2.UID()
        self._select_organization(gic2.UID())
        # police is added at the end of existing groups
        self.assertEqual(get_organizations(the_objects=False),
                         [self.developers_uid, self.vendors_uid,
                          bourg_grp.UID(),
                          police.UID(), police_compta.UID(),
                          gic1.UID(), gic2.UID()])
        # set groupsInCharge for police groups
        police.groups_in_charge = (gic1_uid,)
        police_compta.groups_in_charge = (gic1_uid,)
        self.vendors.groups_in_charge = (gic1_uid,)
        self.developers.groups_in_charge = (gic2_uid,)
        # make 'pmManager' able to manage everything for 'vendors' and 'police'
        groupsTool = self.portal.portal_groups
        for org in (self.vendors, police, police_compta):
            org_uid = org.UID()
            for suffix in get_all_suffixes(org_uid):
                groupsTool.addPrincipalToGroup('pmManager', '{0}_{1}'.format(org_uid, suffix))

        self._removeConfigObjectsFor(self.meetingConfig,
                                     folders=['recurringitems', 'itemtemplates', 'categories'])
        self._createCategories()
        self._createItemTemplates()