예제 #1
0
def group_unassignment(event):
    """
        manage the remove of a user in a plone group
    """
    invalidate_cachekey_volatile_for('imio.dms.mail.vocabularies.AssignedUsersWithDeactivatedVocabulary')
    invalidate_cachekey_volatile_for('imio.dms.mail.vocabularies.AssignedUsersForFacetedFilterVocabulary')
    if event.group_id.endswith(CREATING_GROUP_SUFFIX):
        invalidate_cachekey_volatile_for('imio.dms.mail.vocabularies.ActiveCreatingGroupVocabulary')
    # we update dms config
    if 'n_plus_' in event.group_id:
        update_transitions_auc_config('dmsincomingmail', action='remove', group_id=event.group_id)  # i_e ok
        update_transitions_levels_config(['dmsincomingmail', 'dmsoutgoingmail', 'task'], action='remove',  # i_e ok
                                         group_id=event.group_id)
    # we manage the personnel-folder person and held position
    orgs = organizations_with_suffixes([event.group_id], ['encodeur'], group_as_str=True)
    if orgs:
        userid = event.principal
        portal = api.portal.get()
        pf = portal['contacts']['personnel-folder']
        exist = portal.portal_catalog.unrestrictedSearchResults(mail_type=userid, portal_type='person')
        if userid in pf:
            pers = pf[userid]
        elif exist:
            pers = exist[0]._unrestrictedGetObject()
        else:
            return
        hps = [b._unrestrictedGetObject() for b in
               portal.portal_catalog.unrestrictedSearchResults(path='/'.join(pers.getPhysicalPath()),
                                                               portal_type='held_position')]
        for hp in hps:
            if hp.get_organization().UID() == orgs[0] and api.content.get_state(hp) == 'active':
                api.content.transition(hp, 'deactivate')
예제 #2
0
def group_assignment(event):
    """
        manage the add of a user in a plone group
    """
    invalidate_cachekey_volatile_for('imio.dms.mail.vocabularies.AssignedUsersWithDeactivatedVocabulary')
    invalidate_cachekey_volatile_for('imio.dms.mail.vocabularies.AssignedUsersForFacetedFilterVocabulary')
    if event.group_id.endswith(CREATING_GROUP_SUFFIX):
        invalidate_cachekey_volatile_for('imio.dms.mail.vocabularies.ActiveCreatingGroupVocabulary')
    # we update dms config
    if 'n_plus_' in event.group_id:
        update_transitions_auc_config('dmsincomingmail', action='add', group_id=event.group_id)  # i_e ok
        update_transitions_levels_config(['dmsincomingmail', 'dmsoutgoingmail', 'task'], action='add',  # i_e ok
                                         group_id=event.group_id)
    # we manage the 'lu' label for a new assignment
    # same functions as IncomingMailInCopyGroupUnreadCriterion
    userid = event.principal
    orgs = organizations_with_suffixes([event.group_id], IM_READER_SERVICE_FUNCTIONS, group_as_str=True)
    if orgs:
        days_back = 5
        start = datetime.datetime(1973, 2, 12)
        end = datetime.datetime.now() - datetime.timedelta(days=days_back)
        catalog = api.portal.get_tool('portal_catalog')
        for brain in catalog(portal_type=['dmsincomingmail', 'dmsincoming_email'], recipient_groups=orgs,
                             labels={'not': ['%s:lu' % userid]},
                             created={'query': (start, end), 'range': 'min:max'}):
            # if not brain.recipient_groups:
            #    continue
            obj = brain.getObject()
            labeling = ILabeling(obj)
            user_ids = labeling.storage.setdefault('lu', PersistentList())  # _p_changed is managed
            user_ids.append(userid)  # _p_changed is managed
            obj.reindexObject(idxs=['labels'])
    # we manage the personnel-folder person and held position
    orgs = organizations_with_suffixes([event.group_id], ['encodeur'], group_as_str=True)
    if orgs:
        user = api.user.get(userid)
        start = api.portal.get_registry_record('omail_fullname_used_form', IImioDmsMailConfig, default='firstname')
        firstname, lastname = separate_fullname(user, start=start)
        portal = api.portal.get()
        intids = getUtility(IIntIds)
        pf = portal['contacts']['personnel-folder']
        # exists already
        exist = portal.portal_catalog.unrestrictedSearchResults(mail_type=userid, portal_type='person')
        if userid in pf:
            pers = pf[userid]
        elif exist:
            pers = exist[0]._unrestrictedGetObject()
        else:
            pers = api.content.create(container=pf, type='person', id=userid, userid=userid, lastname=lastname,
                                      firstname=firstname, use_parent_address=False)
        if api.content.get_state(pers) == 'deactivated':
            api.content.transition(pers, 'activate')
        hps = [b._unrestrictedGetObject() for b in
               portal.portal_catalog.unrestrictedSearchResults(path='/'.join(pers.getPhysicalPath()),
                                                               portal_type='held_position')]
        hps_orgs = dict([(hp.get_organization(), hp) for hp in hps])
        uid = orgs[0]
        org = uuidToObject(uid, unrestricted=True)
        if not org:
            return
        if uid in pers:
            hp = pers[uid]
        elif org in hps_orgs:
            hp = hps_orgs[org]
        else:
            hp = api.content.create(container=pers, id=uid, type='held_position',
                                    email=safe_unicode(user.getProperty('email').lower()),
                                    position=RelationValue(intids.getId(org)), use_parent_address=True)
        if api.content.get_state(hp) == 'deactivated':
            api.content.transition(hp, 'activate')
예제 #3
0
def group_deleted(event):
    """
        Raises exception if group cannot be deleted
    """
    group = event.principal
    portal = api.portal.get()
    request = portal.REQUEST

    # is protected group
    if group in ('createurs_dossier', 'dir_general', 'encodeurs', 'expedition', 'lecteurs_globaux_cs',
                 'lecteurs_globaux_ce', 'Administrators', 'Reviewers', 'Site Administrators'):
        api.portal.show_message(message=_("You cannot delete the group '${group}'.", mapping={'group': group}),
                                request=request, type='error')
        raise Redirect(request.get('ACTUAL_URL'))

    parts = group.split('_')
    if len(parts) == 1:
        return
    group_suffix = '_'.join(parts[1:])

    # invalidate vocabularies caches
    invalidate_cachekey_volatile_for('imio.dms.mail.vocabularies.CreatingGroupVocabulary')
    invalidate_cachekey_volatile_for('imio.dms.mail.vocabularies.ActiveCreatingGroupVocabulary')

    def get_query(portal_type, field_p, idx_p, org, suffix):
        fti = getUtility(IDexterityFTI, name=portal_type)
        # try:
        #     fti = getUtility(IDexterityFTI, name=portal_type)
        # except ComponentLookupError:
        #     return {}
        config = getattr(fti, 'localroles', {}).get(field, None)
        if not config:
            return {}
        for st in config:
            if suffix in config[st]:
                return {idx: org}
        return {}

    # search in indexes following suffix use in type localroles
    for (idx, field, pts, domain) in (
            ('assigned_group', 'assigned_group', ['task'], 'collective.eeafaceted.z3ctable'),
            ('treating_groups', 'treating_groups',
             # ['dmsincomingmail', 'dmsincoming_email', 'dmsoutgoingmail', 'dmsoutgoing_email'], here under too
             ['dmsincomingmail', 'dmsincoming_email', 'dmsoutgoingmail'],
             'collective.eeafaceted.z3ctable'),
            ('recipient_groups', 'recipient_groups',
             ['dmsincomingmail', 'dmsincoming_email', 'dmsoutgoingmail'],
             'collective.eeafaceted.z3ctable'),
            ('assigned_group', 'creating_group',
             ['dmsincomingmail', 'dmsincoming_email', 'dmsoutgoingmail'],
             'collective.eeafaceted.z3ctable')):
        for pt in pts:
            query = get_query(pt, field, idx, parts[0], group_suffix)
            if not query:
                continue
            query.update({'portal_type': pt})
            brains = portal.portal_catalog.unrestrictedSearchResults(**query)
            if brains:
                api.portal.show_message(message=_("You cannot delete the group '${group}', used in '${idx}' index.",
                                                  mapping={'group': group, 'idx': translate(idx, domain=domain,
                                                                                            context=request)}),
                                        request=request, type='error')
                api.portal.show_message(message=_("Linked objects: ${list}", mapping={'list': ', '.join(['<a href="%s" '
                                        'target="_blank">%s</a>' % (b.getURL(), safe_unicode(b.Title))
                                        for b in brains])}),
                                        request=request, type='error')
                raise Redirect(request.get('ACTUAL_URL'))

    # we update dms config
    if 'n_plus_' in group:
        update_transitions_auc_config('dmsincomingmail', action='delete', group_id=group)  # i_e ok
        update_transitions_levels_config(['dmsincomingmail', 'dmsoutgoingmail', 'task'], action='delete',  # i_e ok
                                         group_id=group)
예제 #4
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
예제 #5
0
 def test_update_transitions_auc_config(self):
     api.portal.set_registry_record(AUC_RECORD, u'no_check')
     # no check
     config = get_dms_config(['transitions_auc', 'dmsincomingmail'])
     self.assertSetEqual(set(config.keys()), {'close', 'propose_to_agent'})
     self.assertTrue(all(
         config['propose_to_agent'].values()))  # can always do transition
     self.assertTrue(all(
         config['close'].values()))  # can always do transition
     # n_plus_1
     api.portal.set_registry_record(AUC_RECORD, u'n_plus_1')
     # only one transition
     config = get_dms_config(['transitions_auc', 'dmsincomingmail'])
     self.assertSetEqual(set(config.keys()), {'close', 'propose_to_agent'})
     self.assertTrue(all(config['propose_to_agent'].values()))
     self.assertTrue(all(config['close'].values()))
     # we simulate the adding of a level without user
     org1, org2 = get_registry_organizations()[0:2]
     api.group.create('{}_n_plus_1'.format(org1), 'N+1')
     set_dms_config(['wf_from_to', 'dmsincomingmail', 'n_plus', 'to'],
                    [('closed', 'close'),
                     ('proposed_to_agent', 'propose_to_agent'),
                     ('proposed_to_n_plus_1', 'propose_to_n_plus_1')])
     update_transitions_auc_config('dmsincomingmail')
     config = get_dms_config(['transitions_auc', 'dmsincomingmail'])
     self.assertSetEqual(
         set(config.keys()),
         {'close', 'propose_to_n_plus_1', 'propose_to_agent'})
     self.assertTrue(all(config['propose_to_n_plus_1'].values()))
     self.assertTrue(all(config['propose_to_agent'].values()))
     self.assertTrue(all(config['close'].values()))
     # we simulate the adding of a level and a user
     update_transitions_auc_config('dmsincomingmail', 'add',
                                   '{}_n_plus_1'.format(org1))
     config = get_dms_config(['transitions_auc', 'dmsincomingmail'])
     self.assertTrue(config['propose_to_n_plus_1'][org1])
     self.assertFalse(config['propose_to_agent']
                      [org1])  # cannot do transition because user
     self.assertTrue(config['propose_to_agent'][org2])
     # mandatory
     # reset config
     set_dms_config(['transitions_auc', 'dmsincomingmail'], value='dict')
     set_dms_config(['wf_from_to', 'dmsincomingmail', 'n_plus', 'to'],
                    [('closed', 'close'),
                     ('proposed_to_agent', 'propose_to_agent')])
     api.portal.set_registry_record(AUC_RECORD, 'mandatory')
     config = get_dms_config(['transitions_auc', 'dmsincomingmail'])
     self.assertFalse(any(
         config['propose_to_agent'].values()))  # all is False
     self.assertTrue(all(config['close'].values()))
     # we simulate the adding of a level without user
     set_dms_config(['wf_from_to', 'dmsincomingmail', 'n_plus', 'to'],
                    [('closed', 'close'),
                     ('proposed_to_agent', 'propose_to_agent'),
                     ('proposed_to_n_plus_1', 'propose_to_n_plus_1')])
     update_transitions_auc_config('dmsincomingmail')
     config = get_dms_config(['transitions_auc', 'dmsincomingmail'])
     self.assertSetEqual(
         set(config.keys()),
         {'close', 'propose_to_n_plus_1', 'propose_to_agent'})
     self.assertFalse(any(
         config['propose_to_n_plus_1'].values()))  # all is False
     self.assertFalse(any(
         config['propose_to_agent'].values()))  # all is False
     self.assertTrue(all(config['close'].values()))
     # we simulate the adding of a level and a user
     update_transitions_auc_config('dmsincomingmail', 'add',
                                   '{}_n_plus_1'.format(org1))
     config = get_dms_config(['transitions_auc', 'dmsincomingmail'])
     self.assertTrue(config['propose_to_n_plus_1']
                     [org1])  # can do transition because user
     self.assertFalse(config['propose_to_n_plus_1'][org2])
     self.assertFalse(config['propose_to_agent'][org1])
     self.assertFalse(config['propose_to_agent'][org2])
예제 #6
0
def imiodmsmail_settings_changed(event):
    """ Manage a record change """
    if (IRecordModifiedEvent.providedBy(event) and event.record.interfaceName
            and event.record.interface != IImioDmsMailConfig):
        return
    if event.record.fieldName == 'mail_types':
        invalidate_cachekey_volatile_for(
            'imio.dms.mail.vocabularies.IMMailTypesVocabulary')
        invalidate_cachekey_volatile_for(
            'imio.dms.mail.vocabularies.IMActiveMailTypesVocabulary')
    if event.record.fieldName == 'omail_types':
        invalidate_cachekey_volatile_for(
            'imio.dms.mail.vocabularies.OMMailTypesVocabulary')
        invalidate_cachekey_volatile_for(
            'imio.dms.mail.vocabularies.OMActiveMailTypesVocabulary')
    if event.record.fieldName == 'assigned_user_check':
        update_transitions_auc_config('dmsincomingmail')  # i_e ok
        n_plus_x = 'imio.dms.mail.wfadaptations.IMServiceValidation' in \
                   [adapt['adaptation'] for adapt in get_applied_adaptations()]
        snoi = False
        if event.newValue == u'no_check' or not n_plus_x:
            snoi = True
        portal = api.portal.get()
        folder = portal['incoming-mail']['mail-searches']
        if folder['to_treat_in_my_group'].showNumberOfItems != snoi:
            folder['to_treat_in_my_group'].showNumberOfItems = snoi  # noqa
            folder['to_treat_in_my_group'].reindexObject()
    if event.record.fieldName in ('org_templates_encoder_can_edit',
                                  'org_email_templates_encoder_can_edit'):
        folder_id = ('email' in event.record.fieldName) and 'oem' or 'om'
        portal = api.portal.get()
        main_folder = portal.templates[folder_id]
        s_orgs = get_registry_organizations()
        roles = ['Reader']
        all_roles = ['Reader', 'Contributor', 'Editor']
        if api.portal.get_registry_record(event.record.__name__):
            roles = list(all_roles)
        for uid in s_orgs:
            if uid not in main_folder:
                continue
            folder = main_folder[uid]
            groupname = '{}_encodeur'.format(uid)
            api.group.revoke_roles(groupname=groupname,
                                   roles=all_roles,
                                   obj=folder)
            api.group.grant_roles(groupname=groupname, roles=roles, obj=folder)

    if event.record.fieldName == 'imail_group_encoder':
        if api.portal.get_registry_record(
                'imio.dms.mail.browser.settings.IImioDmsMailConfig.imail_group_encoder'
        ):
            configure_group_encoder(['dmsincomingmail', 'dmsincoming_email'])
    if event.record.fieldName == 'omail_group_encoder':
        if api.portal.get_registry_record(
                'imio.dms.mail.browser.settings.IImioDmsMailConfig.omail_group_encoder'
        ):
            # configure_group_encoder(['dmsoutgoingmail', 'dmsoutgoing_email'])
            configure_group_encoder(['dmsoutgoingmail'])
    if event.record.fieldName == 'contact_group_encoder':
        if api.portal.get_registry_record(
                'imio.dms.mail.browser.settings.IImioDmsMailConfig.contact_group_encoder'
        ):
            configure_group_encoder(
                ['organization', 'person', 'held_position', 'contact_list'],
                contacts_part=True)
            # set permission on contacts directory
            portal = api.portal.get()
            portal['contacts'].manage_permission(
                'imio.dms.mail: Write mail base fields',
                ('Manager', 'Site Administrator', 'Contributor'),
                acquire=1)
    if event.record.fieldName == 'groups_hidden_in_dashboard_filter':
        invalidate_cachekey_volatile_for(
            'imio.dms.mail.vocabularies.TreatingGroupsForFacetedFilterVocabulary'
        )
    if event.record.fieldName == 'users_hidden_in_dashboard_filter':
        invalidate_cachekey_volatile_for(
            'imio.dms.mail.vocabularies.AssignedUsersForFacetedFilterVocabulary'
        )
    if event.record.__name__ == 'imio.dms.mail.imail_folder_period' and event.newValue is not None:
        portal = api.portal.get()
        setattr(portal[MAIN_FOLDERS['dmsincomingmail']], 'folder_period',
                event.newValue)
    if event.record.__name__ == 'imio.dms.mail.omail_folder_period' and event.newValue is not None:
        portal = api.portal.get()
        setattr(portal[MAIN_FOLDERS['dmsoutgoingmail']], 'folder_period',
                event.newValue)