def test_detectContactPlonegroupChangeSelectOrgs(self):
     """When selecting 'fct_orgs' on a function, Plone groups are create/deleted depending
        on the fact that 'fct_orgs' is empty or contains some organization uids."""
     own_orga = get_own_organization()
     dep1 = own_orga['department1']
     dep1_uid = dep1.UID()
     dep2 = own_orga['department2']
     dep2_uid = dep2.UID()
     dep1_plone_group_id = get_plone_group_id(dep1_uid, 'director')
     dep2_plone_group_id = get_plone_group_id(dep2_uid, 'director')
     self.assertTrue(api.group.get(dep1_plone_group_id))
     self.assertTrue(api.group.get(dep2_plone_group_id))
     # select dep2_uid for 'director'
     functions = get_registry_functions()
     functions[0]['fct_orgs'] = [dep2_uid]
     set_registry_functions(functions)
     # dep1 director Plone group is deleted
     self.assertFalse(api.group.get(dep1_plone_group_id))
     self.assertTrue(api.group.get(dep2_plone_group_id))
     # select dep1_uid for 'director'
     functions = get_registry_functions()
     functions[0]['fct_orgs'] = [dep1_uid]
     set_registry_functions(functions)
     self.assertTrue(api.group.get(dep1_plone_group_id))
     self.assertFalse(api.group.get(dep2_plone_group_id))
     # select nothing for 'director', every groups are created
     functions = get_registry_functions()
     functions[0]['fct_orgs'] = []
     set_registry_functions(functions)
     self.assertTrue(api.group.get(dep1_plone_group_id))
     self.assertTrue(api.group.get(dep2_plone_group_id))
     # select both dep1 and dep2, every groups are created
     functions = get_registry_functions()
     functions[0]['fct_orgs'] = [dep1_uid, dep2_uid]
     set_registry_functions(functions)
     self.assertTrue(api.group.get(dep1_plone_group_id))
     self.assertTrue(api.group.get(dep2_plone_group_id))
     # Changing function title
     dep1_plone_group = api.group.get(dep1_plone_group_id)
     self.assertEquals(dep1_plone_group.getProperty('title'), 'Department 1 (Director)')
     dep2_plone_group = api.group.get(dep2_plone_group_id)
     self.assertEquals(dep2_plone_group.getProperty('title'), 'Department 2 (Director)')
     functions[0]['fct_title'] = u'New title'
     set_registry_functions(functions)
     dep1_plone_group = api.group.get(dep1_plone_group_id)
     self.assertEquals(dep1_plone_group.getProperty('title'), 'Department 1 (New title)')
     dep2_plone_group = api.group.get(dep2_plone_group_id)
     self.assertEquals(dep2_plone_group.getProperty('title'), 'Department 2 (New title)')
コード例 #2
0
 def test_detectContactPlonegroupChangeSelectOrgs(self):
     """When selecting 'fct_orgs' on a function, Plone groups are create/deleted depending
        on the fact that 'fct_orgs' is empty or contains some organization uids."""
     own_orga = get_own_organization()
     dep1 = own_orga['department1']
     dep1_uid = dep1.UID()
     dep2 = own_orga['department2']
     dep2_uid = dep2.UID()
     dep1_plone_group_id = get_plone_group_id(dep1_uid, 'director')
     dep2_plone_group_id = get_plone_group_id(dep2_uid, 'director')
     self.assertTrue(api.group.get(dep1_plone_group_id))
     self.assertTrue(api.group.get(dep2_plone_group_id))
     # select dep2_uid for 'director'
     functions = get_registry_functions()
     functions[0]['fct_orgs'] = [dep2_uid]
     set_registry_functions(functions)
     # dep1 director Plone group is deleted
     self.assertFalse(api.group.get(dep1_plone_group_id))
     self.assertTrue(api.group.get(dep2_plone_group_id))
     # select dep1_uid for 'director'
     functions = get_registry_functions()
     functions[0]['fct_orgs'] = [dep1_uid]
     set_registry_functions(functions)
     self.assertTrue(api.group.get(dep1_plone_group_id))
     self.assertFalse(api.group.get(dep2_plone_group_id))
     # select nothing for 'director', every groups are created
     functions = get_registry_functions()
     functions[0]['fct_orgs'] = []
     set_registry_functions(functions)
     self.assertTrue(api.group.get(dep1_plone_group_id))
     self.assertTrue(api.group.get(dep2_plone_group_id))
     # select both dep1 and dep2, every groups are created
     functions = get_registry_functions()
     functions[0]['fct_orgs'] = [dep1_uid, dep2_uid]
     set_registry_functions(functions)
     self.assertTrue(api.group.get(dep1_plone_group_id))
     self.assertTrue(api.group.get(dep2_plone_group_id))
     # Changing function title
     dep1_plone_group = api.group.get(dep1_plone_group_id)
     self.assertEquals(dep1_plone_group.getProperty('title'), 'Department 1 (Director)')
     dep2_plone_group = api.group.get(dep2_plone_group_id)
     self.assertEquals(dep2_plone_group.getProperty('title'), 'Department 2 (Director)')
     functions[0]['fct_title'] = u'New title'
     set_registry_functions(functions)
     dep1_plone_group = api.group.get(dep1_plone_group_id)
     self.assertEquals(dep1_plone_group.getProperty('title'), 'Department 1 (New title)')
     dep2_plone_group = api.group.get(dep2_plone_group_id)
     self.assertEquals(dep2_plone_group.getProperty('title'), 'Department 2 (New title)')
コード例 #3
0
 def update_site(self):
     # update front-page
     frontpage = self.portal['front-page']
     if frontpage.Title() == 'Gestion du courrier 2.2':
         frontpage.setTitle(_("front_page_title"))
         frontpage.setDescription(_("front_page_descr"))
         frontpage.setText(_("front_page_text"), mimetype='text/html')
     # update portal title
     self.portal.title = 'Gestion du courrier 2.3'
     # set om folder as default page
     self.portal.templates.setDefaultPage('om')
     # change permission to remove dashboard from user menu
     self.portal.manage_permission('Portlets: Manage own portlets',
                                   ('Manager', 'Site Administrator'),
                                   acquire=0)
     # clean old messages
     if 'doc' in self.portal['messages-config']:
         api.content.delete(self.portal['messages-config']['doc'])
     add_message(
         'doc',
         'Documentation',
         u'<p>Vous pouvez consulter la <a href="https://docs.imio.be/'
         u'imio-doc/ia.docs/" target="_blank">documentation en ligne de la '
         u'version 2.3</a>, dont <a href="https://docs.imio.be/imio-doc/ia.docs/changelog" '
         u'target="_blank">les nouvelles fonctionnalités</a> ainsi que d\'autres documentations liées.</p>',
         msg_type='significant',
         can_hide=True,
         req_roles=['Authenticated'],
         activate=True)
     if 'new-version' in self.portal['messages-config']:
         api.content.delete(self.portal['messages-config']['new-version'])
     # update plonegroup
     if not get_registry_groups_mgt():
         set_registry_groups_mgt(['dir_general', 'encodeurs', 'expedition'])
         functions = get_registry_functions()
         for dic in functions:
             if dic['fct_id'] == u'encodeur':
                 dic['fct_title'] = u'Créateur CS'
         set_registry_functions(functions)
     # add group
     if api.group.get('lecteurs_globaux_ce') is None:
         api.group.create('lecteurs_globaux_ce', '2 Lecteurs Globaux CE')
     # change local roles
     fti = getUtility(IDexterityFTI, name='dmsincomingmail')  # i_e ok
     lr = getattr(fti, 'localroles')
     lrsc = lr['static_config']
     for state in [
             'proposed_to_manager', 'proposed_to_n_plus_1',
             'proposed_to_agent', 'in_treatment', 'closed'
     ]:
         if state in lrsc:
             if 'lecteurs_globaux_ce' not in lrsc[state]:
                 lrsc[state]['lecteurs_globaux_ce'] = {'roles': ['Reader']}
     lr._p_changed = True  # We need to indicate that the object has been modified and must be "saved"
     # mark tabs to add count on
     for folder_id in ('incoming-mail', 'outgoing-mail', 'tasks'):
         folder = self.portal[folder_id]
         if not ICountableTab.providedBy(folder):
             alsoProvides(folder, ICountableTab)
             folder.reindexObject(idxs='object_provides')
コード例 #4
0
 def test_validateSettingsRemoveFunction(self):
     """A function may only be removed if every linked Plone groups are empty."""
     # add a user to group department1 director
     own_orga = get_own_organization()
     dep1 = own_orga['department1']
     plone_group_id = get_plone_group_id(dep1.UID(), 'director')
     api.group.add_user(groupname=plone_group_id, username=TEST_USER_ID)
     invariants = validator.InvariantsValidator(
         None, None, None, settings.IContactPlonegroupConfig, None)
     orgs = get_registry_organizations()
     functions = get_registry_functions()
     data = {'organizations': orgs, 'functions': functions}
     # for now it validates correctly
     self.assertFalse(invariants.validate(data))
     # remove 'director'
     functions.pop(0)
     errors = invariants.validate(data)
     self.assertTrue(isinstance(errors[0], Invalid))
     error_msg = translate(
         msgid=u"can_not_remove_function_every_plone_groups_not_empty",
         domain='collective.contact.plonegroup',
         mapping={'removed_function': 'director',
                  'plone_group_id': plone_group_id})
     self.assertEqual(translate(errors[0].message), error_msg)
     # remove user from plone group, now it validates
     api.group.remove_user(groupname=plone_group_id, username=TEST_USER_ID)
     self.assertFalse(invariants.validate(data))
コード例 #5
0
 def test_validateSettingsSelectFunctionOrgsOnExistingFunction(self):
     """Selecting 'fct_orgs' for an existing function (so for which Plone groups are already created),
        is only possible if groups that will be deleted (Plone groups of organizations not selected
        as 'fct_orgs') are empty."""
     # add a user to group department1 director
     own_orga = get_own_organization()
     dep1 = own_orga['department1']
     dep2 = own_orga['department2']
     plone_group_id = get_plone_group_id(dep1.UID(), 'director')
     api.group.add_user(groupname=plone_group_id, username=TEST_USER_ID)
     invariants = validator.InvariantsValidator(
         None, None, None, settings.IContactPlonegroupConfig, None)
     orgs = get_registry_organizations()
     functions = get_registry_functions()
     data = {'organizations': orgs, 'functions': functions}
     # set dep2 as 'fct_orgs' of 'director' function
     director = functions[0]
     director['fct_orgs'] = [dep2.UID()]
     errors = invariants.validate(data)
     self.assertTrue(isinstance(errors[0], Invalid))
     error_msg = translate(
         msgid=u"can_not_select_function_orgs_every_other_plone_groups_not_empty",
         domain='collective.contact.plonegroup',
         mapping={'function': 'director',
                  'plone_group_id': plone_group_id})
     self.assertEqual(translate(errors[0].message), error_msg)
     # remove user from plone group, now it validates
     api.group.remove_user(groupname=plone_group_id, username=TEST_USER_ID)
     self.assertFalse(invariants.validate(data))
コード例 #6
0
 def AssignedUsersWithDeactivatedVocabulary__call__(self, context):
     factory = getUtility(IVocabularyFactory, 'plone.principalsource.Users')
     vocab = factory(context)  # terms as username, userid, fullname
     a_terms = []
     d_terms = []
     active_orgs = get_registry_organizations()
     functions = [dic['fct_id'] for dic in get_registry_functions()]
     for term in vocab:
         for group in api.group.get_groups(username=term.value):
             if group.id == 'AuthenticatedUsers':
                 continue
             parts = group.id.split('_')
             if len(parts) != 1:
                 group_suffix = '_'.join(parts[1:])
                 if group_suffix in functions and parts[
                         0] not in active_orgs:  # not an active org
                     continue
             term.title = term.title.decode('utf8')
             a_terms.append(term)
             break
         else:
             term.title = _tr(
                 '${element_title} (Inactive)',
                 mapping={'element_title': safe_unicode(term.title)})
             d_terms.append(term)
     return SimpleVocabulary(
         [SimpleTerm(EMPTY_STRING, EMPTY_STRING, _('Empty value'))] +
         humansorted(a_terms, key=attrgetter('title')) +
         humansorted(d_terms, key=attrgetter('title')))
コード例 #7
0
 def test_TaskServiceValidation1(self):
     """ Test TaskServiceValidation adaptations """
     # is function added
     self.assertIn('n_plus_1',
                   [fct['fct_id'] for fct in get_registry_functions()])
     # is local roles modified
     fti = getUtility(IDexterityFTI, name='task')
     lr = getattr(fti, 'localroles')
     self.assertIn('n_plus_1', lr['assigned_group']['to_do'])
     self.assertIn('n_plus_1', lr['parents_assigned_groups']['to_do'])
     for ptype in ('ClassificationFolder', 'ClassificationSubfolder'):
         fti = getUtility(IDexterityFTI, name=ptype)
         lr = getattr(fti, 'localroles')
         self.assertIn('n_plus_1', lr['treating_groups']['active'], ptype)
         self.assertIn('n_plus_1', lr['recipient_groups']['active'], ptype)
     # check collection
     folder = self.portal['tasks']['task-searches']
     self.assertTrue(folder['to_assign'].enabled)
     self.assertTrue(folder['to_close'].enabled)
     self.assertFalse(folder['to_treat_in_my_group'].showNumberOfItems)
     # check annotations
     config = get_dms_config(['review_levels', 'task'])
     self.assertIn('_n_plus_1', config)
     config = get_dms_config(['review_states', 'task'])
     self.assertIn('to_assign', config)
     self.assertIn('realized', config)
 def test_validateSettingsSelectFunctionOrgsOnExistingFunction(self):
     """Selecting 'fct_orgs' for an existing function (so for which Plone groups are already created),
        is only possible if groups that will be deleted (Plone groups of organizations not selected
        as 'fct_orgs') are empty."""
     # add a user to group department1 director
     own_orga = get_own_organization()
     dep1 = own_orga['department1']
     dep2 = own_orga['department2']
     plone_group_id = get_plone_group_id(dep1.UID(), 'director')
     api.group.add_user(groupname=plone_group_id, username=TEST_USER_ID)
     invariants = validator.InvariantsValidator(
         None, None, None, settings.IContactPlonegroupConfig, None)
     orgs = get_registry_organizations()
     functions = get_registry_functions()
     data = {'organizations': orgs, 'functions': functions}
     # set dep2 as 'fct_orgs' of 'director' function
     director = functions[0]
     director['fct_orgs'] = [dep2.UID()]
     errors = invariants.validate(data)
     self.assertTrue(isinstance(errors[0], Invalid))
     error_msg = translate(
         msgid=u"can_not_select_function_orgs_every_other_plone_groups_not_empty",
         domain='collective.contact.plonegroup',
         mapping={'function': 'director',
                  'plone_group_id': plone_group_id})
     self.assertEqual(translate(errors[0].message), error_msg)
     # remove user from plone group, now it validates
     api.group.remove_user(groupname=plone_group_id, username=TEST_USER_ID)
     self.assertFalse(invariants.validate(data))
 def test_validateSettingsDisableFunction(self):
     """A function may only be disabled (enabled=False)
        if every linked Plone groups are empty."""
     # add a user to group department1 director
     own_orga = get_own_organization()
     dep1 = own_orga['department1']
     plone_group_id = get_plone_group_id(dep1.UID(), 'director')
     api.group.add_user(groupname=plone_group_id, username=TEST_USER_ID)
     invariants = validator.InvariantsValidator(
         None, None, None, settings.IContactPlonegroupConfig, None)
     orgs = get_registry_organizations()
     functions = get_registry_functions()
     data = {'organizations': orgs, 'functions': functions}
     # for now it validates correctly
     self.assertFalse(invariants.validate(data))
     # disable 'director'
     functions[0]['enabled'] = False
     errors = invariants.validate(data)
     self.assertTrue(isinstance(errors[0], Invalid))
     error_msg = translate(
         msgid=u"can_not_disable_suffix_plone_groups_not_empty",
         domain='collective.contact.plonegroup',
         mapping={'removed_function': 'director',
                  'plone_group_id': plone_group_id})
     self.assertEqual(translate(errors[0].message), error_msg)
     # remove user from plone group, now it validates
     api.group.remove_user(groupname=plone_group_id, username=TEST_USER_ID)
     self.assertFalse(invariants.validate(data))
コード例 #10
0
def activate_group_encoder(self, typ='imail'):
    """ Clean created examples """
    if not check_role(self):
        return "You must be a manager to run this script"
    portal = api.portal.getSite()
    # activate group encoder
    api.portal.set_registry_record('imio.dms.mail.browser.settings.IImioDmsMailConfig.{}_group_encoder'.format(typ),
                                   True)
    # we add organizations
    orgs = [portal['contacts']['plonegroup-organization']['direction-generale']['secretariat'].UID(),
            portal['contacts']['plonegroup-organization']['evenements'].UID()]
    functions = get_registry_functions()
    for dic in functions:
        if dic['fct_id'] != CREATING_GROUP_SUFFIX:
            continue
        if not dic['fct_orgs']:
            dic['fct_orgs'] = orgs
    set_registry_functions(functions)
    # we add members in groups
    if 'encodeur' not in [u.getId() for u in
                          api.user.get_users(groupname='{}_{}'.format(orgs[0], CREATING_GROUP_SUFFIX))]:
        api.group.add_user(groupname='{}_{}'.format(orgs[0], CREATING_GROUP_SUFFIX), username='******')
        api.group.add_user(groupname='{}_{}'.format(orgs[1], CREATING_GROUP_SUFFIX), username='******')

    return portal.REQUEST.response.redirect(portal.absolute_url())
コード例 #11
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'])
コード例 #12
0
 def __call__(self, context):
     functions = get_registry_functions()
     terms = []
     for function in functions:
         terms.append(
             SimpleTerm(function['fct_id'],
                        function['fct_id'],
                        function['fct_title']))
     return SimpleVocabulary(terms)
def addOrModifyOrganizationGroups(organization, uid):
    """
        Modify groups linked to an organization
    """
    changes = False
    for dic in get_registry_functions():
        if addOrModifyGroup(organization, dic['fct_id'], dic['fct_title']):
            changes = True
    return changes
コード例 #14
0
 def test_select_org_for_function(self):
     """ """
     self.assertEqual(get_registry_functions(), [{
         'fct_title': u'Observers',
         'fct_orgs': [],
         'fct_id': u'observer',
         'fct_management': False,
         'enabled': True
     }, {
         'fct_title': u'Director',
         'fct_orgs': [],
         'fct_id': u'director',
         'fct_management': False,
         'enabled': True
     }])
     select_org_for_function(self.uid, 'director')
     self.assertTrue(self.uid in get_registry_functions()[1]['fct_orgs'])
     select_org_for_function(self.uid, 'director', remove=True)
     self.assertFalse(self.uid in get_registry_functions()[1]['fct_orgs'])
コード例 #15
0
def select_org_for_function(org_uid, function_id, remove=False):
    """Select an organization UID in the list of fct_orgs of a function."""
    functions = get_registry_functions()
    for function in functions:
        if function['fct_id'] == function_id:
            if remove and org_uid in function['fct_orgs']:
                function['fct_orgs'].remove(org_uid)
            elif org_uid not in function['fct_orgs']:
                function['fct_orgs'].append(org_uid)
    set_registry_functions(functions)
コード例 #16
0
def select_org_for_function(org_uid, function_id, remove=False):
    """Select an organization UID in the list of fct_orgs of a function."""
    functions = get_registry_functions()
    for function in functions:
        if function['fct_id'] == function_id:
            if remove and org_uid in function['fct_orgs']:
                function['fct_orgs'].remove(org_uid)
            elif org_uid not in function['fct_orgs']:
                function['fct_orgs'].append(org_uid)
    set_registry_functions(functions)
コード例 #17
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'])
コード例 #18
0
def get_all_suffixes(org_uid=None, only_enabled=True):
    """
        Get every suffixes defined in the configuration.
    """
    functions = get_registry_functions()
    return [
        function['fct_id'] for function in functions
        if (not only_enabled or function['enabled']) and (
            not org_uid or not function['fct_orgs']
            or org_uid in function['fct_orgs'])
    ]
 def test_detectContactPlonegroupChangeDisableFunction(self):
     """When a function is disabled (enabled=False), every linked Plone groups are deleted as well.
        This is protected by validateSettings that checks first that every Plone groups are empty."""
     own_orga = get_own_organization()
     dep1 = own_orga['department1']
     plone_group_id = get_plone_group_id(dep1.UID(), 'director')
     self.assertTrue(api.group.get(plone_group_id))
     functions = get_registry_functions()
     # disable 'director'
     functions[0]['enabled'] = False
     set_registry_functions(functions)
     # the linked Plone groups are deleted
     self.assertFalse(api.group.get(plone_group_id))
コード例 #20
0
 def test_detectContactPlonegroupChangeRemoveFunction(self):
     """When a function is removed, every linked Plone groups are deleted as well.
        This is protected by validateSettings that checks first that every Plone groups are empty."""
     own_orga = get_own_organization()
     dep1 = own_orga['department1']
     plone_group_id = get_plone_group_id(dep1.UID(), 'director')
     self.assertTrue(api.group.get(plone_group_id))
     functions = get_registry_functions()
     # remove 'director'
     functions.pop(0)
     set_registry_functions(functions)
     # the linked Plone groups are deleted
     self.assertFalse(api.group.get(plone_group_id))
 def test_detectContactPlonegroupChange(self):
     """Test if group creation works correctly"""
     group_ids = [group.id for group in api.group.get_groups()]
     organizations = get_registry_organizations()
     for uid in organizations:
         self.assertIn('%s_director' % uid, group_ids)
         self.assertIn('%s_worker' % uid, group_ids)
     d1_d_group = api.group.get(groupname='%s_director' % organizations[0])
     self.assertEquals(d1_d_group.getProperty('title'), 'Department 1 (Director)')
     d1s1_d_group = api.group.get(groupname='%s_director' % organizations[1])
     self.assertEquals(d1s1_d_group.getProperty('title'), 'Department 1 - Service 1 (Director)')
     # Changing function title
     set_registry_functions([{'fct_title': u'Directors',
                              'fct_id': u'director',
                              'fct_orgs': [],
                              'fct_management': False,
                              'enabled': True},
                             {'fct_title': u'Worker',
                              'fct_id': u'worker',
                              'fct_orgs': [],
                              'fct_management': False,
                              'enabled': True}])
     d1_d_group = api.group.get(groupname='%s_director' % organizations[0])
     self.assertEquals(d1_d_group.getProperty('title'), 'Department 1 (Directors)')
     d1s1_d_group = api.group.get(groupname='%s_director' % organizations[1])
     self.assertEquals(d1s1_d_group.getProperty('title'), 'Department 1 - Service 1 (Directors)')
     # Adding new organization
     own_orga = get_own_organization()
     own_orga['department2'].invokeFactory('organization', 'service2', title='Service 2')
     # append() method on the registry doesn't trigger the event. += too
     newValue = get_registry_organizations() + [own_orga['department2']['service2'].UID()]
     set_registry_organizations(newValue)
     group_ids = [group.id for group in api.group.get_groups()]
     last_uid = get_registry_organizations()[-1]
     self.assertIn('%s_director' % last_uid, group_ids)
     self.assertIn('%s_worker' % last_uid, group_ids)
     # Adding new function
     newValue = get_registry_functions() + [{'fct_title': u'Chief',
                                             'fct_id': u'chief',
                                             'fct_orgs': [],
                                             'fct_management': False,
                                             'enabled': True}]
     set_registry_functions(newValue)
     group_ids = [group.id for group in api.group.get_groups() if '_' in group.id]
     self.assertEquals(len(group_ids), 12)
     for uid in get_registry_organizations():
         self.assertIn('%s_director' % uid, group_ids)
         self.assertIn('%s_chief' % uid, group_ids)
         self.assertIn('%s_worker' % uid, group_ids)
コード例 #22
0
 def test_onlyRelevantPloneGroupsCreatedWhenFunctionRestrictedToSelectedOrgs(self):
     """Test using 'fct_orgs' when defining functions."""
     # create a new suffix and restrict it to department1
     own_orga = get_own_organization()
     dep1 = own_orga['department1']
     dep1_uid = dep1.UID()
     dep2 = own_orga['department2']
     dep2_uid = dep2.UID()
     functions = get_registry_functions()
     new_function = {'fct_id': u'new', 'fct_title': u'New', 'fct_orgs': [dep1_uid]}
     functions.append(new_function)
     set_registry_functions(functions)
     # 'new' suffixed Plone group was created only for dep1
     self.assertTrue(api.group.get(get_plone_group_id(dep1_uid, u'new')))
     self.assertFalse(api.group.get(get_plone_group_id(dep2_uid, u'new')))
 def test_onlyRelevantPloneGroupsCreatedWhenFunctionRestrictedToSelectedOrgs(self):
     """Test using 'fct_orgs' when defining functions."""
     # create a new suffix and restrict it to department1
     own_orga = get_own_organization()
     dep1 = own_orga['department1']
     dep1_uid = dep1.UID()
     dep2 = own_orga['department2']
     dep2_uid = dep2.UID()
     functions = get_registry_functions()
     new_function = {'fct_id': u'new',
                     'fct_title': u'New',
                     'fct_orgs': [dep1_uid],
                     'fct_management': False,
                     'enabled': True}
     functions.append(new_function)
     set_registry_functions(functions)
     # 'new' suffixed Plone group was created only for dep1
     self.assertTrue(api.group.get(get_plone_group_id(dep1_uid, u'new')))
     self.assertFalse(api.group.get(get_plone_group_id(dep2_uid, u'new')))
コード例 #24
0
 def test_detectContactPlonegroupChange(self):
     """Test if group creation works correctly"""
     group_ids = [group.id for group in api.group.get_groups()]
     organizations = get_registry_organizations()
     for uid in organizations:
         self.assertIn('%s_director' % uid, group_ids)
         self.assertIn('%s_worker' % uid, group_ids)
     d1_d_group = api.group.get(groupname='%s_director' % organizations[0])
     self.assertEquals(d1_d_group.getProperty('title'), 'Department 1 (Director)')
     d1s1_d_group = api.group.get(groupname='%s_director' % organizations[1])
     self.assertEquals(d1s1_d_group.getProperty('title'), 'Department 1 - Service 1 (Director)')
     # Changing function title
     set_registry_functions([{'fct_title': u'Directors', 'fct_id': u'director', 'fct_orgs': []},
                             {'fct_title': u'Worker', 'fct_id': u'worker', 'fct_orgs': []}])
     d1_d_group = api.group.get(groupname='%s_director' % organizations[0])
     self.assertEquals(d1_d_group.getProperty('title'), 'Department 1 (Directors)')
     d1s1_d_group = api.group.get(groupname='%s_director' % organizations[1])
     self.assertEquals(d1s1_d_group.getProperty('title'), 'Department 1 - Service 1 (Directors)')
     # Adding new organization
     own_orga = get_own_organization()
     own_orga['department2'].invokeFactory('organization', 'service2', title='Service 2')
     # append() method on the registry doesn't trigger the event. += too
     newValue = get_registry_organizations() + [own_orga['department2']['service2'].UID()]
     set_registry_organizations(newValue)
     group_ids = [group.id for group in api.group.get_groups()]
     last_uid = get_registry_organizations()[-1]
     self.assertIn('%s_director' % last_uid, group_ids)
     self.assertIn('%s_worker' % last_uid, group_ids)
     # Adding new function
     newValue = get_registry_functions() + [{'fct_title': u'Chief', 'fct_id': u'chief', 'fct_orgs': []}]
     set_registry_functions(newValue)
     group_ids = [group.id for group in api.group.get_groups() if '_' in group.id]
     self.assertEquals(len(group_ids), 12)
     for uid in get_registry_organizations():
         self.assertIn('%s_director' % uid, group_ids)
         self.assertIn('%s_chief' % uid, group_ids)
         self.assertIn('%s_worker' % uid, group_ids)
コード例 #25
0
 def test_IMServiceValidation1(self):
     """
         Test IMServiceValidation adaptations
     """
     # is function added
     self.assertIn('n_plus_1',
                   [fct['fct_id'] for fct in get_registry_functions()])
     # is local roles modified
     for ptype in ('dmsincomingmail', 'dmsincoming_email'):
         fti = getUtility(IDexterityFTI, name=ptype)
         lr = getattr(fti, 'localroles')
         self.assertIn('proposed_to_n_plus_1', lr['static_config'], ptype)
         self.assertIn('proposed_to_n_plus_1', lr['treating_groups'], ptype)
         self.assertIn('proposed_to_n_plus_1', lr['recipient_groups'],
                       ptype)
     for ptype in ('ClassificationFolder', 'ClassificationSubfolder'):
         fti = getUtility(IDexterityFTI, name=ptype)
         lr = getattr(fti, 'localroles')
         self.assertIn('n_plus_1', lr['treating_groups']['active'], ptype)
         self.assertIn('n_plus_1', lr['recipient_groups']['active'], ptype)
     # check collection
     folder = self.portal['incoming-mail']['mail-searches']
     self.assertIn('searchfor_proposed_to_n_plus_1', folder)
     self.assertEqual(
         folder.getObjectPosition('searchfor_proposed_to_agent'), 13)
     self.assertEqual(
         folder.getObjectPosition('searchfor_proposed_to_n_plus_1'), 12)
     self.assertFalse(folder['to_treat_in_my_group'].showNumberOfItems)
     # check annotations
     config = get_dms_config(['review_levels', 'dmsincomingmail'])
     self.assertIn('_n_plus_1', config)
     config = get_dms_config(['review_states', 'dmsincomingmail'])
     self.assertIn('proposed_to_n_plus_1', config)
     config = get_dms_config(['transitions_auc', 'dmsincomingmail'])
     self.assertIn('propose_to_n_plus_1', config)
     config = get_dms_config(['transitions_levels', 'dmsincomingmail'])
     self.assertEqual(config['proposed_to_manager'].values()[0][0],
                      'propose_to_n_plus_1')
     self.assertEqual(config['proposed_to_agent'].values()[0][1],
                      'back_to_n_plus_1')
     wf_from_to = get_dms_config(
         ['wf_from_to', 'dmsincomingmail', 'n_plus'])
     self.assertListEqual(wf_from_to['to'],
                          [('closed', 'close'),
                           ('proposed_to_agent', 'propose_to_agent'),
                           ('proposed_to_n_plus_1', 'propose_to_n_plus_1')])
     # check vocabularies
     factory = getUtility(
         IVocabularyFactory,
         u'collective.eeafaceted.collectionwidget.cachedcollectionvocabulary'
     )
     self.assertEqual(len(factory(folder, folder)), 16)
     factory = getUtility(IVocabularyFactory,
                          u'imio.dms.mail.IMReviewStatesVocabulary')
     self.assertEqual(len(factory(folder)), 6)
     # check configuration
     lst = api.portal.get_registry_record(
         'imio.actionspanel.browser.registry.IImioActionsPanelConfig.transitions'
     )
     self.assertIn('dmsincomingmail.back_to_n_plus_1|', lst)
     self.assertIn('dmsincoming_email.back_to_n_plus_1|', lst)
     lst = api.portal.get_registry_record(
         'imio.dms.mail.browser.settings.IImioDmsMailConfig.imail_remark_states'
     )
     self.assertIn('proposed_to_n_plus_1', lst)
コード例 #26
0
 def test_OMServiceValidation1(self):
     """
         Test OMServiceValidation adaptations
     """
     # is function added
     self.assertIn('n_plus_1',
                   [fct['fct_id'] for fct in get_registry_functions()])
     # is local roles modified
     fti = getUtility(IDexterityFTI, name='dmsoutgoingmail')
     lr = getattr(fti, 'localroles')
     self.assertIn('proposed_to_n_plus_1', lr['treating_groups'])
     self.assertIn('proposed_to_n_plus_1', lr['recipient_groups'])
     self.assertIn('validated', lr['treating_groups'])
     self.assertIn('validated', lr['recipient_groups'])
     for ptype in ('ClassificationFolder', 'ClassificationSubfolder'):
         fti = getUtility(IDexterityFTI, name=ptype)
         lr = getattr(fti, 'localroles')
         self.assertIn('n_plus_1', lr['treating_groups']['active'], ptype)
         self.assertIn('n_plus_1', lr['recipient_groups']['active'], ptype)
     # check collection
     folder = self.portal['outgoing-mail']['mail-searches']
     self.assertIn('searchfor_proposed_to_n_plus_1', folder)
     self.assertIn('searchfor_validated', folder)
     self.assertEqual(
         folder.getObjectPosition('searchfor_proposed_to_n_plus_1'), 10)
     self.assertEqual(folder.getObjectPosition('searchfor_validated'), 11)
     self.assertEqual(folder.getObjectPosition('searchfor_to_be_signed'),
                      12)
     self.assertIn('proposed_to_n_plus_1', [
         dic['v'] for dic in folder['om_treating'].query
         if dic['i'] == 'review_state'
     ][0])
     self.assertIn('validated', [
         dic['v'] for dic in folder['om_treating'].query
         if dic['i'] == 'review_state'
     ][0])
     self.assertTrue(folder['to_validate'].enabled)
     # check annotations
     config = get_dms_config(['review_levels', 'dmsoutgoingmail'])
     self.assertIn('_n_plus_1', config)
     config = get_dms_config(['review_states', 'dmsoutgoingmail'])
     self.assertIn('proposed_to_n_plus_1', config)
     # check vocabularies
     factory = getUtility(
         IVocabularyFactory,
         u'collective.eeafaceted.collectionwidget.cachedcollectionvocabulary'
     )
     self.assertEqual(len(factory(folder, folder)), 14)
     factory = getUtility(IVocabularyFactory,
                          u'imio.dms.mail.OMReviewStatesVocabulary')
     self.assertEqual(len(factory(folder)), 6)
     # check configuration
     lst = api.portal.get_registry_record(
         'imio.actionspanel.browser.registry.IImioActionsPanelConfig.transitions'
     )
     self.assertIn('dmsoutgoingmail.back_to_n_plus_1|', lst)
     self.assertIn('dmsoutgoingmail.back_to_validated|', lst)
     lst = api.portal.get_registry_record(
         'imio.dms.mail.browser.settings.IImioDmsMailConfig.omail_remark_states'
     )
     self.assertIn('proposed_to_n_plus_1', lst)
     self.assertIn('validated', lst)
コード例 #27
0
    def remove_useless_functions(self):
        """
        Remove groups that are not used in our custom workflow
        """
        def filter_list(list, filter_out):
            kept = []
            for item in list:
                if item not in filter_out:
                    kept.append(item)
            return kept

        for cfg in self.tool.objectValues("MeetingConfig"):
            adviceAnnexConfidentialVisibleFor = filter_list(
                list(cfg.getAdviceAnnexConfidentialVisibleFor()),
                [
                    "suffix_proposing_group_prereviewers",
                    "suffix_proposing_group_budgetimpactreviewers",
                    "suffix_proposing_group_reviewers",
                ],
            )
            cfg.setAdviceAnnexConfidentialVisibleFor(
                adviceAnnexConfidentialVisibleFor)

            itemAnnexConfidentialVisibleFor = filter_list(
                list(cfg.getItemAnnexConfidentialVisibleFor()),
                [
                    "suffix_proposing_group_prereviewers",
                    "suffix_proposing_group_budgetimpactreviewers",
                    "suffix_proposing_group_reviewers",
                ],
            )
            cfg.setItemAnnexConfidentialVisibleFor(
                itemAnnexConfidentialVisibleFor)

            meetingAnnexConfidentialVisibleFor = filter_list(
                list(cfg.getMeetingAnnexConfidentialVisibleFor()),
                [
                    "suffix_profile_prereviewers",
                    "suffix_profile_budgetimpactreviewers",
                    "suffix_profile_reviewers",
                ],
            )
            cfg.setMeetingAnnexConfidentialVisibleFor(
                meetingAnnexConfidentialVisibleFor)
            cfg.processForm()
            cfg.reindexObject()

        groups = api.group.get_groups()
        for group in groups:
            grp_id = group.id
            if grp_id.endswith("_reviewers") or grp_id.endswith(
                    "_prereviewers"):
                for member in group.getAllGroupMemberIds():
                    group.removeMember(member)

        functions = get_registry_functions()
        functions_result = []
        for function in functions:
            if function["fct_id"] not in (u"prereviewers", u"reviewers"):
                functions_result.append(function)

        set_registry_functions(functions_result)
コード例 #28
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)
コード例 #29
0
    def remove_service_chief(self):
        # remove collection
        logger.info('Modifying workflows')
        for folder in (self.imf['mail-searches'], self.omf['mail-searches']):
            if 'searchfor_proposed_to_service_chief' in folder:
                api.content.delete(
                    obj=folder['searchfor_proposed_to_service_chief'])

        # clean dms config
        for ptype in ('dmsincomingmail', 'dmsoutgoingmail', 'task'):  # i_e ok
            config = get_dms_config(['review_levels', ptype])
            if '_validateur' in config:
                del config['_validateur']
                set_dms_config(keys=['review_levels', ptype], value=config)
            config = get_dms_config(['review_states', ptype])
            if 'proposed_to_service_chief' in config:
                del config['proposed_to_service_chief']
                set_dms_config(keys=['review_states', ptype], value=config)

        def remove_localrole_validateur(dic1):
            for state1 in dic1:
                if 'validateur' in dic1[state1]:
                    del dic1[state1]['validateur']

        # clean local roles
        for ptype in ('dmsincomingmail', 'dmsoutgoingmail'):  # i_e ok
            fti = getUtility(IDexterityFTI, name=ptype)
            lr = getattr(fti, 'localroles')
            lrg = lr['static_config']
            if 'proposed_to_service_chief' in lrg:
                del lrg['proposed_to_service_chief']
                remove_localrole_validateur(lrg)
            lrg = lr['treating_groups']
            if 'proposed_to_service_chief' in lrg:
                del lrg['proposed_to_service_chief']
                remove_localrole_validateur(lrg)
            lrg = lr['recipient_groups']
            if 'proposed_to_service_chief' in lrg:
                del lrg['proposed_to_service_chief']
                remove_localrole_validateur(lrg)
            lr._p_changed = True
        # on task
        fti = getUtility(IDexterityFTI, name='task')
        lr = getattr(fti, 'localroles')
        lrg = lr['assigned_group']
        if 'validateur' in lrg['to_do']:
            remove_localrole_validateur(lrg)
        lrg = lr['parents_assigned_groups']
        if 'validateur' in lrg['to_do']:
            remove_localrole_validateur(lrg)
        lr._p_changed = True

        # update registry
        lst = api.portal.get_registry_record(
            'imio.actionspanel.browser.registry.IImioActionsPanelConfig.transitions'
        )
        for entry in ('dmsincomingmail.back_to_service_chief|',
                      'dmsoutgoingmail.back_to_service_chief|'):
            if entry not in lst:
                break
            lst.remove(entry)
        else:
            api.portal.set_registry_record(
                'imio.actionspanel.browser.registry.IImioActionsPanelConfig.transitions',
                lst)

        # update remark states
        for attr in ('imail_remark_states', 'omail_remark_states'):
            lst = (api.portal.get_registry_record(
                'imio.dms.mail.browser.settings.IImioDmsMailConfig.{}'.format(
                    attr)) or [])
            if 'proposed_to_service_chief' in lst:
                lst.remove('proposed_to_service_chief')
                api.portal.set_registry_record(
                    'imio.dms.mail.browser.settings.IImioDmsMailConfig.{}'.
                    format(attr), lst)

        # Manage workflows and wfadaptations
        functions = get_registry_functions()
        if 'validateur' not in [fct['fct_id'] for fct in functions]:
            return  # apply the following only once

        def remove_adaptation_from_registry(name):
            record = api.portal.get_registry_record(RECORD_NAME)
            api.portal.set_registry_record(
                RECORD_NAME, [d for d in record if d['adaptation'] != name])

        # reset workflows
        self.runProfileSteps('imio.dms.mail', steps=['workflow'])
        # self.portal.portal_workflow.updateRoleMappings()  # done later

        # Apply workflow adaptations if necessary
        applied_wfa = [dic['adaptation'] for dic in get_applied_adaptations()]
        n_plus_1_params = {
            'validation_level': 1,
            'state_title': u'À valider par le chef de service',
            'forward_transition_title': u'Proposer au chef de service',
            'backward_transition_title': u'Renvoyer au chef de service',
            'function_title': u'N+1'
        }
        task_adapt = True
        for wkf, acr in (('incomingmail_workflow', 'IM'),
                         ('outgoingmail_workflow', 'OM')):
            if u'imio.dms.mail.wfadaptations.{}SkipProposeToServiceChief'.format(
                    acr) in applied_wfa:
                remove_adaptation_from_registry(
                    u'imio.dms.mail.wfadaptations.{}SkipProposeToServiceChief'.
                    format(acr))
                task_adapt = False
                if acr == 'OM':
                    folder = self.omf['mail-searches']
                    if folder['to_validate'].enabled:
                        folder['to_validate'].enabled = False
                        folder['to_validate'].reindexObject()
            else:
                logger.info(
                    'Applying {}ServiceValidation wf adaptation'.format(acr))
                sva = getattr(wfadaptations,
                              '{}ServiceValidation'.format(acr))()
                sva.reapply = True
                adapt_is_applied = sva.patch_workflow(wkf, **n_plus_1_params)
                if adapt_is_applied:
                    add_applied_adaptation(
                        'imio.dms.mail.wfadaptations.{}ServiceValidation'.
                        format(acr), wkf, True, **n_plus_1_params)

        # update task_workflow
        update_task_workflow(self.portal)
        if task_adapt:
            tsva = TaskServiceValidation()
            adapt_is_applied = tsva.patch_workflow('task_workflow', **{})
            if adapt_is_applied:
                add_applied_adaptation(
                    'imio.dms.mail.wfadaptations.TaskServiceValidation',
                    'task_workflow', False)
        else:
            # update collections
            folder = self.portal['tasks']['task-searches']
            for cid in ('to_assign', 'to_close'):
                if folder[cid].enabled:
                    folder[cid].enabled = False
                    folder[cid].reindexObject()

        invalidate_cachekey_volatile_for(
            'collective.eeafaceted.collectionwidget.cachedcollectionvocabulary'
        )

        # replace EmergencyZoneAdaptation
        im_workflow = self.wtool['incomingmail_workflow']
        if u'imio.dms.mail.wfadaptations.EmergencyZone' in applied_wfa:
            state = im_workflow.states['proposed_to_manager']
            state.title = u'À valider par le CZ'.encode('utf8')
            for tr, tit in (('back_to_manager', u'Renvoyer au CZ'),
                            ('propose_to_manager', u'Proposer au CZ')):
                transition = im_workflow.transitions[tr]
                transition.title = tit.encode('utf8')
            logger.info('Removing EmergencyZone wf adaptation')
            remove_adaptation_from_registry(
                u'imio.dms.mail.wfadaptations.EmergencyZone')

        # redo OMToPrintAdaptation
        if u'imio.dms.mail.wfadaptations.OMToPrint' in applied_wfa:
            logger.info('Applying OMToPrint wf adaptation')
            tpa = OMToPrintAdaptation()
            tpa.patch_workflow('outgoingmail_workflow')

        # redo IMPreManagerValidation
        if u'imio.dms.mail.wfadaptations.IMPreManagerValidation' in applied_wfa:
            logger.info('Applying IMPreManagerValidation wf adaptation')
            params = [
                dic['parameters'] for dic in get_applied_adaptations()
                if dic['adaptation'] ==
                u'imio.dms.mail.wfadaptations.IMPreManagerValidation'
            ][0]
            remove_adaptation_from_registry(
                u'imio.dms.mail.wfadaptations.IMPreManagerValidation')
            del params['collection_title']
            pmva = IMPreManagerValidation()
            adapt_is_applied = pmva.patch_workflow('incomingmail_workflow',
                                                   **params)
            if adapt_is_applied:
                add_applied_adaptation(
                    'imio.dms.mail.wfadaptations.IMPreManagerValidation',
                    'incoming_mail', False, **params)

        # update wf history to replace review_state and correct history
        config = {
            'dmsincomingmail': {
                'wf': 'incomingmail_workflow',  # i_e ok
                'st': {
                    'proposed_to_service_chief': 'proposed_to_n_plus_1'
                },
                'tr': {
                    'propose_to_service_chief': 'propose_to_n_plus_1',
                    'back_to_service_chief': 'back_to_n_plus_1'
                }
            },
            'dmsoutgoingmail': {
                'wf': 'outgoingmail_workflow',
                'st': {
                    'proposed_to_service_chief': 'proposed_to_n_plus_1'
                },
                'tr': {
                    'propose_to_service_chief': 'propose_to_n_plus_1',
                    'back_to_service_chief': 'back_to_n_plus_1'
                }
            }
        }
        for pt in config:
            logger.info('Updating history and indexes of {} type'.format(pt))
            for i, brain in enumerate(self.catalog(portal_type=pt), 1):
                obj = brain.getObject()
                if i % 10000 == 0:
                    logger.info('On brain {}'.format(i))
                # update history
                wfh = []
                wkf = self.wtool[config[pt]['wf']]
                for status in obj.workflow_history.get(config[pt]['wf']):
                    # replace old state by new one
                    if status['review_state'] in config[pt]['st']:
                        status['review_state'] = config[pt]['st'][
                            status['review_state']]
                    # replace old transition by new one
                    if status['action'] in config[pt]['tr']:
                        status['action'] = config[pt]['tr'][status['action']]
                    wfh.append(status)
                obj.workflow_history[config[pt]['wf']] = tuple(wfh)
                # update permissions and roles
                wkf.updateRoleMappingsFor(obj)
                # update state_group (use dms_config), permissions, state
                obj.reindexObject(idxs=[
                    'allowedRolesAndUsers', 'review_state', 'state_group'
                ])
                for child in obj.objectValues():
                    child.reindexObject(idxs=['allowedRolesAndUsers'])

        # migrate plone groups
        # First unregister group deletion handlers
        globalSiteManager.unregisterHandler(pg_group_deleted,
                                            (IGroupDeletedEvent, ))
        globalSiteManager.unregisterHandler(group_deleted,
                                            (IGroupDeletedEvent, ))
        globalSiteManager.unregisterHandler(group_assignment,
                                            (IPrincipalAddedToGroupEvent, ))
        globalSiteManager.unregisterHandler(
            group_unassignment, (IPrincipalRemovedFromGroupEvent, ))
        # move users from _validateur to _n_plus_1
        for group in api.group.get_groups():
            if group.id.endswith('_validateur'):
                org = group.id.split('_')[0]
                np1group = api.group.get('{}_n_plus_1'.format(org))
                if np1group:
                    for user in api.user.get_users(group=group):
                        api.group.add_user(group=np1group, user=user)
                        api.group.remove_user(group=group, user=user)
                api.group.delete(group=group)
        # register again group deletion handlers
        globalSiteManager.registerHandler(pg_group_deleted,
                                          (IGroupDeletedEvent, ))
        globalSiteManager.registerHandler(group_deleted,
                                          (IGroupDeletedEvent, ))
        globalSiteManager.registerHandler(group_assignment,
                                          (IPrincipalAddedToGroupEvent, ))
        globalSiteManager.registerHandler(group_unassignment,
                                          (IPrincipalRemovedFromGroupEvent, ))

        # remove validateur function
        functions = get_registry_functions()
        if 'validateur' in [fct['fct_id'] for fct in functions]:
            set_registry_functions(
                [fct for fct in functions if fct['fct_id'] != 'validateur'])
コード例 #30
0
 def get_manageable_functions(self):
     """ get all manageable functions """
     for fct in get_registry_functions(as_copy=False):
         if fct['fct_management']:
             self.functions[fct['fct_id']] = fct['fct_title']
     return self.functions.keys()
def detectContactPlonegroupChange(event):
    """
        Manage our record changes
    """
    if IRecordModifiedEvent.providedBy(
            event):  # and event.record.interface == IContactPlonegroupConfig:
        changes = False
        # this can be called before plonegroup is installed and registry contains relevant keys
        try:
            registry_orgs = get_registry_organizations()
        except InvalidParameterError:
            registry_orgs = []
        if event.record.fieldName == 'organizations' and registry_orgs:
            old_set = set(event.oldValue)
            new_set = set(event.newValue)
            # we detect a new organization
            add_set = new_set.difference(old_set)
            for orga_uid in add_set:
                orga = uuidToObject(orga_uid)
                for fct_dic in get_registry_functions():
                    enabled = fct_dic['enabled']
                    if enabled is False:
                        continue
                    fct_orgs = fct_dic['fct_orgs']
                    if fct_orgs and orga_uid not in fct_orgs:
                        continue
                    if addOrModifyGroup(orga, fct_dic['fct_id'],
                                        fct_dic['fct_title']):
                        changes = True
            # we detect a removed organization. We dont do anything on exsiting groups
            if old_set.difference(new_set):
                changes = True
        elif event.record.fieldName == 'functions' and registry_orgs:
            old_functions = {
                dic['fct_id']: {
                    'fct_title': dic['fct_title'],
                    'fct_orgs': dic['fct_orgs'],
                    'enabled': dic['enabled']
                }
                for dic in event.oldValue
            }
            old_set = set(old_functions.keys())
            new_functions = {
                dic['fct_id']: {
                    'fct_title': dic['fct_title'],
                    'fct_orgs': dic['fct_orgs'],
                    'enabled': dic['enabled']
                }
                for dic in event.newValue
            }
            new_set = set(new_functions.keys())
            # we detect a new function
            add_set = new_set.difference(old_set)
            for new_id in add_set:
                new_title = new_functions[new_id]['fct_title']
                new_orgs = new_functions[new_id]['fct_orgs']
                enabled = new_functions[new_id]['enabled']
                for orga_uid in registry_orgs:
                    if new_orgs and orga_uid not in new_orgs:
                        continue
                    if enabled is False:
                        continue
                    orga = uuidToObject(orga_uid)
                    if addOrModifyGroup(orga, new_id, new_title):
                        changes = True
            # we detect a removed function
            # We may remove Plone groups as we checked before that every are empty
            removed_set = old_set.difference(new_set)
            for removed_id in removed_set:
                for orga_uid in get_organizations(only_selected=False,
                                                  the_objects=False):
                    plone_group_id = get_plone_group_id(orga_uid, removed_id)
                    plone_group = api.group.get(plone_group_id)
                    if plone_group:
                        api.group.delete(plone_group_id)
                        changes = True
            # we detect existing functions for which 'fct_orgs' changed
            for new_id, new_function_infos in new_functions.items():
                new_title = new_function_infos['fct_title']
                new_orgs = new_function_infos['fct_orgs']
                enabled = new_function_infos['enabled']
                if not new_orgs and enabled is True:
                    # we have to make sure Plone groups are created for every selected organizations
                    for orga_uid in registry_orgs:
                        orga = uuidToObject(orga_uid)
                        if addOrModifyGroup(orga, new_id, new_title):
                            changes = True
                else:
                    # fct_orgs changed, we remove every linked Plone groups
                    # except ones defined in new_orgs
                    for orga_uid in get_organizations(only_selected=False,
                                                      the_objects=False):
                        if enabled is True and orga_uid in new_orgs:
                            # make sure Plone group is created or updated if suffix title changed
                            orga = uuidToObject(orga_uid)
                            if addOrModifyGroup(orga, new_id, new_title):
                                changes = True
                        else:
                            # make sure Plone group is deleted
                            plone_group_id = get_plone_group_id(
                                orga_uid, new_id)
                            plone_group = api.group.get(plone_group_id)
                            if plone_group:
                                api.group.delete(plone_group_id)
                                changes = True

        if changes:
            invalidate_sopgv_cache()
            invalidate_sov_cache()
            invalidate_soev_cache()
            invalidate_ssoev_cache()
コード例 #32
0
    def test_configure_group_encoder(self):
        setRoles(self.portal, TEST_USER_ID, ['Manager'])
        # activate imail group encoder
        activate_group_encoder(self.portal)
        self.assertIn(CREATING_GROUP_SUFFIX,
                      [fct['fct_id'] for fct in get_registry_functions()])
        for portal_type in ('dmsincomingmail', 'dmsincoming_email'):
            fti = getUtility(IDexterityFTI, name=portal_type)
            self.assertIn(
                'imio.dms.mail.content.behaviors.IDmsMailCreatingGroup',
                fti.behaviors)
            self.assertIn('creating_group',
                          [tup[0] for tup in get_localrole_fields(fti)])
            self.assertTrue(
                fti.localroles.get('creating_group'))  # config dic not empty
        crit = ICriteria(self.portal['incoming-mail']['mail-searches'])
        self.assertIn('c90', crit.keys())
        fields = api.portal.get_registry_record(
            'imio.dms.mail.browser.settings.IImioDmsMailConfig.imail_fields')
        self.assertIn('IDmsMailCreatingGroup.creating_group',
                      [f['field_name'] for f in fields])

        # activate omail group encoder
        activate_group_encoder(self.portal, typ='omail')
        self.assertIn(CREATING_GROUP_SUFFIX,
                      [fct['fct_id'] for fct in get_registry_functions()])
        # for portal_type in ('dmsoutgoingmail', 'dmsoutgoing_email'):
        for portal_type in ('dmsoutgoingmail', ):
            fti = getUtility(IDexterityFTI, name=portal_type)
            self.assertIn(
                'imio.dms.mail.content.behaviors.IDmsMailCreatingGroup',
                fti.behaviors, portal_type)
            self.assertIn('creating_group',
                          [tup[0] for tup in get_localrole_fields(fti)],
                          portal_type)
            self.assertTrue(fti.localroles.get('creating_group'),
                            portal_type)  # config dic not empty
        crit = ICriteria(self.portal['outgoing-mail']['mail-searches'])
        self.assertIn('c90', crit.keys())
        fields = api.portal.get_registry_record(
            'imio.dms.mail.browser.settings.IImioDmsMailConfig.omail_fields')
        self.assertIn('IDmsMailCreatingGroup.creating_group',
                      [f['field_name'] for f in fields])

        # activate contact group encoder
        activate_group_encoder(self.portal, typ='contact')
        self.assertIn(CREATING_GROUP_SUFFIX,
                      [fct['fct_id'] for fct in get_registry_functions()])
        self.assertIn(CONTACTS_PART_SUFFIX,
                      [fct['fct_id'] for fct in get_registry_functions()])
        for portal_type in ('organization', 'person', 'held_position',
                            'contact_list'):
            fti = getUtility(IDexterityFTI, name=portal_type)
            self.assertIn(
                'imio.dms.mail.content.behaviors.IDmsMailCreatingGroup',
                fti.behaviors)
            self.assertIn('creating_group',
                          [tup[0] for tup in get_localrole_fields(fti)])
        for fid in ('orgs-searches', 'persons-searches', 'hps-searches',
                    'cls-searches'):
            crit = ICriteria(self.portal['contacts'][fid])
            self.assertIn('c90', crit.keys())
コード例 #33
0
    def run(self):
        self.data = self.profileData
        if not self.data:
            return self.noDataMessage
        # Register classes again, after model adaptations have been performed
        # (see comment in __init__.py)
        registerClasses()
        # if we already have existing organizations, we do not add additional ones
        own_org = get_own_organization()
        alreadyHaveGroups = bool(own_org.objectValues())
        savedMeetingConfigsToCloneTo = {}
        savedOrgsData = {}
        if not alreadyHaveGroups or self.data.forceAddUsersAndGroups:
            # 1) create organizations so we have org UIDS to initialize 'fct_orgs'
            orgs, active_orgs, savedOrgsData = self.addOrgs(self.data.orgs)
            # 2) create plonegroup functions (suffixes) to create Plone groups
            functions = get_registry_functions()
            function_ids = [function['fct_id'] for function in functions]
            # append new functions
            suffixes = MEETING_GROUP_SUFFIXES + EXTRA_GROUP_SUFFIXES
            for suffix in suffixes:
                if suffix['fct_id'] not in function_ids:
                    copied_suffix = suffix.copy()
                    copied_suffix['fct_title'] = translate(
                        suffix['fct_title'],
                        domain='PloneMeeting',
                        context=self.request)
                    # if org_path not found, do not fail but log, it is often the case in tests
                    # in which we do not add additional organizations because it breaks some tests
                    copied_suffix['fct_orgs'] = []
                    for org_path in suffix['fct_orgs']:
                        try:
                            fct_org = own_org.restrictedTraverse(org_path)
                        except KeyError:
                            logger.warning(
                                "Could not find an organization with path {0} "
                                "while setting 'fct_orgs' for {1}".format(
                                    org_path, suffix['fct_id']))
                            continue
                        copied_suffix['fct_orgs'].append(fct_org.UID())
                    functions.append(copied_suffix)
            # 3) manage organizations, set every organizations so every Plone groups are created
            # then disable orgs that are not active
            invalidate_soev_cache()
            invalidate_ssoev_cache()
            already_active_orgs = get_registry_organizations()
            org_uids = [
                org_uid for org_uid in get_organizations(only_selected=False,
                                                         the_objects=False)
                if org_uid not in already_active_orgs
            ]
            set_registry_organizations(org_uids)
            set_registry_functions(functions)
            active_org_uids = [org.UID() for org in active_orgs]
            set_registry_organizations(already_active_orgs + active_org_uids)
            # 4) add users to Plone groups
            self.addUsers(self.data.orgs)
            # 5) now that organizations are created, we add persons and held_positions
            self.addPersonsAndHeldPositions(self.data.persons,
                                            source=self.profilePath)

        created_cfgs = []
        for mConfig in self.data.meetingConfigs:
            # XXX we need to defer the management of the 'meetingConfigsToCloneTo'
            # defined on the mConfig after the creation of every mConfigs because
            # if we defined in mConfig1.meetingConfigsToCloneTo the mConfig2 id,
            # it will try to getattr this meetingConfig2 id that does not exist yet...
            # so save defined values, removed them from mConfig and manage that after
            savedMeetingConfigsToCloneTo[
                mConfig.id] = mConfig.meetingConfigsToCloneTo
            mConfig.meetingConfigsToCloneTo = []
            cfg = self.createMeetingConfig(mConfig, source=self.profilePath)
            if cfg:
                created_cfgs.append(cfg)
                self._finishConfigFor(cfg, data=mConfig)

        # manage other_mc_correspondences
        for created_cfg in created_cfgs:
            self._manageOtherMCCorrespondences(created_cfg)

        # now that every meetingConfigs have been created, we can manage the meetingConfigsToCloneTo
        # and orgs advice states related fields
        for mConfigId in savedMeetingConfigsToCloneTo:
            if not savedMeetingConfigsToCloneTo[mConfigId]:
                continue
            # initialize the attribute on the meetingConfig and call _updateCloneToOtherMCActions
            cfg = getattr(self.tool, mConfigId)
            # validate the MeetingConfig.meetingConfigsToCloneTo data that we are about to set
            # first replace cfg1 and cfg2 by corresponding cfg id
            adapted_cfgsToCloneTo = deepcopy(
                savedMeetingConfigsToCloneTo[mConfigId])
            for cfgToCloneTo in adapted_cfgsToCloneTo:
                cfgToCloneTo['meeting_config'] = self.cfg_num_to_id(
                    cfgToCloneTo['meeting_config'])
            error = cfg.validate_meetingConfigsToCloneTo(adapted_cfgsToCloneTo)
            if error:
                raise PloneMeetingError(MEETING_CONFIG_ERROR %
                                        (cfg.Title(), cfg.getId(), error))
            cfg.setMeetingConfigsToCloneTo(adapted_cfgsToCloneTo)
            cfg._updateCloneToOtherMCActions()
        for org_uid, values in savedOrgsData.items():
            org = uuidToObject(org_uid, unrestricted=True)
            # turn cfg1__state__itemcreated into meeting-config-id__state__itemcreated
            org.item_advice_states = self._correct_advice_states(
                values['item_advice_states'])
            org.item_advice_edit_states = self._correct_advice_states(
                values['item_advice_edit_states'])
            org.item_advice_view_states = self._correct_advice_states(
                values['item_advice_view_states'])
            org.groups_in_charge = [
                org_id_to_uid(group_id)
                for group_id in values['groups_in_charge']
            ]

        # finally, create the current user (admin) member area
        self.portal.portal_membership.createMemberArea()
        # at the end, add users outside PloneMeeting groups because
        # they could have to be added in groups created by the MeetingConfig
        if not alreadyHaveGroups:
            # adapt userDescr.ploneGroups to turn cfg_num into cfg_id
            self.addUsersOutsideGroups(self.data.usersOutsideGroups)

        # commit before continuing so elements like scales on annex types are correctly saved
        transaction.commit()
        return self.successMessage
    def test_management_view(self):
        view = self.portal.unrestrictedTraverse('@@manage-own-groups-users')
        # No groups activated
        self.assertListEqual(view.get_manageable_groups(), [])
        self.assertListEqual(view.get_manageable_functions(), [])

        # we activate groups and functions
        functions = get_registry_functions(as_copy=False)
        functions[0]['fct_management'] = True
        set_registry_groups_mgt(['investigators'])
        view.init()
        self.assertListEqual(view.get_manageable_groups(), ['investigators'])
        self.assertListEqual(view.get_manageable_functions(), [u'observer'])
        view.get_user_manageable_groups()  # fill in view.groupids
        view.get_user_manageable_functions()  # fill in view.functions_orgs
        self.assertDictEqual(view.groupids, {})
        self.assertDictEqual(view.functions_orgs, {})

        # we add the current user to the activated groups, so he can manage it
        api.group.add_user(groupname='investigators', username=TEST_USER_ID)
        api.group.add_user(groupname='{}_observer'.format(self.uid),
                           username=TEST_USER_ID)

        def get_user_groups(userid):
            return [
                g.id for g in api.group.get_groups(username=userid)
                if g.id not in ['AuthenticatedUsers']
            ]

        self.assertListEqual(
            get_user_groups(TEST_USER_ID),
            ['{}_observer'.format(self.uid), u'investigators'])
        view = self.portal.unrestrictedTraverse('@@manage-own-groups-users')
        view.init()
        self.assertListEqual(view.get_manageable_groups(), ['investigators'])
        self.assertListEqual(view.get_manageable_functions(), [u'observer'])
        view.get_user_manageable_groups()  # fill in view.groupids
        view.get_user_manageable_functions()  # fill in view.functions_orgs
        self.assertDictEqual(view.groupids,
                             {u'investigators': u'Investigators'})
        self.assertDictEqual(view.functions_orgs, {'observer': [self.dep1]})

        # we check the values given to the fields
        view.update()
        self.assertListEqual(view.fieldnames,
                             ['_groups_', 'observer', '_old_values_'])
        content = view.getContent()
        self.assertListEqual(content._groups_, [{
            'group': u'investigators',
            'user': '******'
        }])
        self.assertListEqual(content.observer, [{
            'group': self.uid,
            'user': '******'
        }])
        old_values = (
            "{{'_groups_': [{{'group': u'investigators', 'user': '******'}}], 'observer': "
            "[{{'group': '{}', 'user': '******'}}]}}".format(self.uid))
        self.assertEqual(content._old_values_, old_values)

        # applying form : we add users
        self.assertListEqual(get_user_groups('dexter'), [])
        self.assertListEqual(get_user_groups('debra'), [])
        data = {
            '_groups_':
            content._groups_ + [{
                'group': u'investigators',
                'user': '******'
            }],
            'observer':
            content.observer + [{
                'group': self.uid,
                'user': '******'
            }],
            '_old_values_':
            old_values
        }
        view.widgets.extract = lambda *a, **kw: (data, [])
        view.handleApply(view, 'apply')
        self.assertListEqual(get_user_groups('dexter'),
                             ['{}_observer'.format(self.uid)])
        self.assertListEqual(get_user_groups('debra'), [u'investigators'])
        # we add/remove users
        data = {
            '_groups_':
            [dic for dic in content._groups_ if dic['user'] != 'debra'] +
            [{
                'group': u'investigators',
                'user': '******'
            }],
            'observer':
            [dic for dic in content.observer if dic['user'] != 'dexter'] +
            [{
                'group': self.uid,
                'user': '******'
            }],
            '_old_values_':
            content._old_values_
        }
        view.widgets.extract = lambda *a, **kw: (data, [])
        view.handleApply(view, 'apply')
        self.assertListEqual(get_user_groups('dexter'), [u'investigators'])
        self.assertListEqual(get_user_groups('debra'),
                             ['{}_observer'.format(self.uid)])

        # we cannot remove current user
        data = {
            '_groups_': [dic for dic in content._groups_ if dic['user'] == ''],
            'observer': [dic for dic in content.observer if dic['user'] == ''],
            '_old_values_': content._old_values_
        }
        view.widgets.extract = lambda *a, **kw: (data, [])
        self.assertRaises(Redirect, view.handleApply, view, 'apply')

        # we cannot handle incomplete data
        data = {
            '_groups_':
            content._groups_ + [{
                'group': u'investigators',
                'user': None
            }],
            'observer':
            content.observer,
            '_old_values_':
            content._old_values_
        }
        view.widgets.extract = lambda *a, **kw: (data, [])
        self.assertRaises(Redirect, view.handleApply, view, 'apply')
    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
                              }))
コード例 #36
0
def contact_plonegroup_change(event):
    """Event handler when contact.plonegroup records are modified.

    * update workflow dms config (new groups).
    * invalidate vocabulary caches.
    * set localroles on contacts for _encodeur groups.
    * add a directory by organization in templates/om, templates/oem and contacts/contact-lists-folder.
    * set local roles on contacts, incoming-mail for group_encoder.
    """
    if (IRecordModifiedEvent.providedBy(event) and event.record.interfaceName and
            event.record.interface == IContactPlonegroupConfig):
        registry = getUtility(IRegistry)
        s_orgs = get_registry_organizations()
        s_fcts = get_registry_functions()
        if not s_fcts or not s_orgs:
            return
        # we update dms config
        update_transitions_auc_config('dmsincomingmail')  # i_e ok
        update_transitions_levels_config(['dmsincomingmail', 'dmsoutgoingmail', 'task'])  # i_e ok
        # invalidate vocabularies caches
        invalidate_cachekey_volatile_for('imio.dms.mail.vocabularies.CreatingGroupVocabulary')
        invalidate_cachekey_volatile_for('imio.dms.mail.vocabularies.ActiveCreatingGroupVocabulary')
        invalidate_cachekey_volatile_for('imio.dms.mail.vocabularies.TreatingGroupsWithDeactivatedVocabulary')
        invalidate_cachekey_volatile_for('imio.dms.mail.vocabularies.TreatingGroupsForFacetedFilterVocabulary')

        portal = api.portal.get()
        # contributor on a contact can edit too
        for folder in (portal['outgoing-mail'], portal['contacts'],
                       portal['contacts']['contact-lists-folder']['common']):
            dic = folder.__ac_local_roles__
            for principal in dic.keys():
                if principal.endswith('_encodeur'):
                    del dic[principal]
            for uid in s_orgs:
                dic["%s_encodeur" % uid] = ['Contributor']
            folder._p_changed = True
        # we add a directory by organization in templates/om
        om_folder = portal.templates.om
        oem_folder = portal.templates.oem
        base_model = om_folder.get('main', None)
        cl_folder = portal.contacts['contact-lists-folder']
        for uid in s_orgs:
            obj = uuidToObject(uid, unrestricted=True)
            full_title = obj.get_full_title(separator=' - ', first_index=1)
            if uid not in om_folder:
                folder = api.content.create(container=om_folder, type='Folder', id=uid, title=full_title)
                # alsoProvides(folder, IActionsPanelFolderOnlyAdd)  # made now in subscriber
                # alsoProvides(folder, INextPrevNotNavigable)
                roles = ['Reader']
                if registry['imio.dms.mail.browser.settings.IImioDmsMailConfig.org_templates_encoder_can_edit']:
                    roles += ['Contributor', 'Editor']
                api.group.grant_roles(groupname='%s_encodeur' % uid, roles=roles, obj=folder)
                folder.reindexObjectSecurity()
                if base_model and base_model.has_been_modified():
                    logger.info("Copying %s in %s" % (base_model, '/'.join(folder.getPhysicalPath())))
                    api.content.copy(source=base_model, target=folder)
            if uid not in oem_folder:
                folder = api.content.create(container=oem_folder, type='Folder', id=uid, title=full_title)
                roles = ['Reader']
                if registry['imio.dms.mail.browser.settings.IImioDmsMailConfig.org_email_templates_encoder_can_edit']:
                    roles += ['Contributor', 'Editor']
                api.group.grant_roles(groupname='%s_encodeur' % uid, roles=roles, obj=folder)
                folder.reindexObjectSecurity()
                # if base_model and base_model.has_been_modified():
                #    logger.info("Copying %s in %s" % (base_model, '/'.join(folder.getPhysicalPath())))
                #    api.content.copy(source=base_model, target=folder)
            if uid not in cl_folder:
                folder = api.content.create(container=cl_folder, type='Folder', id=uid, title=full_title)
                folder.setLayout('folder_tabular_view')
                roles = ['Reader', 'Contributor', 'Editor']
                api.group.grant_roles(groupname='%s_encodeur' % uid, roles=roles, obj=folder)
                folder.reindexObjectSecurity()
        # we manage local roles to give needed permissions related to group_encoder
        options_config = {portal['incoming-mail']: ['imail_group_encoder'],
                          portal['outgoing-mail']: ['omail_group_encoder'],
                          portal['contacts']: ['imail_group_encoder', 'omail_group_encoder', 'contact_group_encoder'],
                          portal['contacts']['contact-lists-folder']['common']: ['imail_group_encoder',
                                                                                 'omail_group_encoder',
                                                                                 'contact_group_encoder']}
        ge_config = {opt: api.portal.get_registry_record('imio.dms.mail.browser.settings.IImioDmsMailConfig.{}'.format(
            opt), default=False) for opt in ('imail_group_encoder', 'omail_group_encoder', 'contact_group_encoder')}

        group_encoder_config = [dic for dic in s_fcts if dic['fct_id'] == CREATING_GROUP_SUFFIX]  # noqa F812
        if group_encoder_config:
            orgs = group_encoder_config[0]['fct_orgs']
            for folder in options_config:
                if any([ge_config[opt] for opt in options_config[folder]]):
                    dic = folder.__ac_local_roles__
                    for principal in dic.keys():
                        if principal.endswith(CREATING_GROUP_SUFFIX):
                            del dic[principal]
                    for uid in orgs:
                        dic["{}_{}".format(uid, CREATING_GROUP_SUFFIX)] = ['Contributor']
                    folder._p_changed = True
コード例 #37
0
def clean_examples(self, doit='1'):
    """ Clean created examples """
    if not check_zope_admin():
        return "You must be a zope manager to run this script"
    if doit == '1':
        doit = True
    else:
        doit = False
    out = []
    portal = api.portal.getSite()
    if doit:
        portal.portal_properties.site_properties.enable_link_integrity_checks = False
    registry = getUtility(IRegistry)

    # Delete om
    brains = find(unrestricted=True, portal_type='dmsoutgoingmail')
    for brain in brains:
        log_list(out, "Deleting om '%s'" % brain.getPath())
        if doit:
            api.content.delete(obj=brain._unrestrictedGetObject(), check_linkintegrity=False)
    if doit:
        registry['collective.dms.mailcontent.browser.settings.IDmsMailConfig.outgoingmail_number'] = 1
    # Create test om
    params = {'title': u'Courrier test pour création de modèles (ne pas effacer)',
              'internal_reference_no': internalReferenceOutgoingMailDefaultValue(DummyView(portal, portal.REQUEST)),
              'mail_date': date.today(),
              'mail_type': 'type1',
              }
    if doit:
        sub_create(portal['outgoing-mail'], 'dmsoutgoingmail', datetime.now(), 'test_creation_modele', **params)

    # Delete im
    brains = find(unrestricted=True, portal_type=['dmsincomingmail', 'dmsincoming_email'])
    for brain in brains:
        log_list(out, "Deleting im '%s'" % brain.getPath())
        if doit:
            api.content.delete(obj=brain._unrestrictedGetObject(), check_linkintegrity=False)
    if doit:
        registry['collective.dms.mailcontent.browser.settings.IDmsMailConfig.incomingmail_number'] = 1
    # Delete own personnel
    pf = portal['contacts']['personnel-folder']
    brains = find(unrestricted=True, context=pf, portal_type='person')
    for brain in brains:
        log_list(out, "Deleting person '%s'" % brain.getPath())
        if doit:
            api.content.delete(obj=brain._unrestrictedGetObject(), check_linkintegrity=False)
    # Deactivate own organizations
    ownorg = portal['contacts']['plonegroup-organization']
    brains = find(unrestricted=True, context=ownorg, portal_type='organization',
                  id=['plonegroup-organization', 'college-communal'])
    kept_orgs = [brain.UID for brain in brains]
    log_list(out, "Activating only 'college-communal'")
    if doit:
        set_registry_organizations([ownorg['college-communal'].UID()])
    # Delete organization and template folders
    tmpl_folder = portal['templates']['om']
    brains = find(unrestricted=True, context=ownorg, portal_type='organization', sort_on='path',
                  sort_order='descending')
    for brain in brains:
        uid = brain.UID
        if uid in kept_orgs:
            continue
        log_list(out, "Deleting organization '%s'" % brain.getPath())
        if doit:
            api.content.delete(obj=brain._unrestrictedGetObject(), check_linkintegrity=False)
        if uid in tmpl_folder:
            log_list(out, "Deleting template folder '%s'" % '/'.join(tmpl_folder[uid].getPhysicalPath()))
            if doit:
                api.content.delete(obj=tmpl_folder[uid])
    # Delete contacts
    brains = find(unrestricted=True, context=portal['contacts'], portal_type='contact_list')
    for brain in brains:
        log_list(out, "Deleting contact list '%s'" % brain.getPath())
        if doit:
            api.content.delete(obj=brain._unrestrictedGetObject(), check_linkintegrity=False)
    brains = find(unrestricted=True, context=portal['contacts'], portal_type='person',
                  id=['jeancourant', 'sergerobinet', 'bernardlermitte'])
    for brain in brains:
        log_list(out, "Deleting person '%s'" % brain.getPath())
        if doit:
            api.content.delete(obj=brain._unrestrictedGetObject(), check_linkintegrity=False)
    brains = find(unrestricted=True, context=portal['contacts'], portal_type='organization', id=['electrabel', 'swde'])
    for brain in brains:
        log_list(out, "Deleting organization '%s'" % brain.getPath())
        if doit:
            api.content.delete(obj=brain._unrestrictedGetObject(), check_linkintegrity=False)
    # Delete users
    for userid in ['encodeur', 'dirg', 'chef', 'agent', 'agent1', 'lecteur']:
        user = api.user.get(userid=userid)
        for brain in find(unrestricted=True, Creator=userid, sort_on='path', sort_order='descending'):
            log_list(out, "Deleting object '%s' created by '%s'" % (brain.getPath(), userid))
            if doit:
                api.content.delete(obj=brain._unrestrictedGetObject(), check_linkintegrity=False)
        for group in api.group.get_groups(user=user):
            if group.id == 'AuthenticatedUsers':
                continue
            log_list(out, "Removing user '%s' from group '%s'" % (userid, group.getProperty('title')))
            if doit:
                api.group.remove_user(group=group, user=user)
        log_list(out, "Deleting user '%s'" % userid)
        if doit:
            api.user.delete(user=user)
    # Delete groups
    functions = [dic['fct_id'] for dic in get_registry_functions()]
    groups = api.group.get_groups()
    for group in groups:
        if '_' not in group.id or group.id in ['createurs_dossier', 'dir_general', 'lecteurs_globaux_ce',
                                               'lecteurs_globaux_cs']:
            continue
        parts = group.id.split('_')
        if len(parts) == 1:
            continue
        org_uid = parts[0]
        function = '_'.join(parts[1:])
        if org_uid in kept_orgs or function not in functions:
            continue
        log_list(out, "Deleting group '%s'" % group.getProperty('title'))
        if doit:
            api.group.delete(group=group)
    # Delete folders
    for brain in find(unrestricted=True, portal_type=('ClassificationFolder', 'ClassificationSubfolder'),
                      sort_on='path', sort_order='descending'):
        log_list(out, "Deleting classification folder '%s'" % brain.getPath())
        if doit:
            api.content.delete(obj=brain._unrestrictedGetObject())
    # Delete categories
    caching.invalidate_cache("collective.classification.tree.utils.iterate_over_tree", portal['tree'].UID())
    res = iterate_over_tree(portal['tree'])
    for category in reversed(res):
        log_list(out, "Deleting category '%s - %s'" % (safe_encode(category.identifier), safe_encode(category.title)))
        if doit:
            api.content.delete(obj=category)
    if doit:
        caching.invalidate_cache("collective.classification.tree.utils.iterate_over_tree", portal['tree'].UID())
        portal.portal_properties.site_properties.enable_link_integrity_checks = True
    return '\n'.join(out)