Projet

Général

Profil

0001-formdata-hold-get_role_translation-function-38254.patch

Nicolas Roche, 13 décembre 2020 17:51

Télécharger (16,1 ko)

Voir les différences:

Subject: [PATCH 1/3] formdata: hold get_role_translation function (#38254)

 wcs/backoffice/management.py |  4 ++--
 wcs/formdata.py              | 24 ++++++++++++++++++------
 wcs/forms/workflows.py       |  3 +--
 wcs/wf/aggregation_email.py  |  5 ++---
 wcs/wf/notification.py       |  4 ++--
 wcs/workflows.py             | 28 ++++++----------------------
 6 files changed, 31 insertions(+), 37 deletions(-)
wcs/backoffice/management.py
59 59
from wcs.forms.backoffice import FormDefUI
60 60
from wcs.forms.common import FormStatusPage
61 61
from wcs.admin.settings import UserFieldsFormDef
62 62
from wcs.categories import Category
63 63
from wcs.formdata import FormData
64 64
from wcs.formdef import FormDef
65 65
from wcs.roles import logged_users_role, Role
66 66
from wcs.variables import LazyFieldVar
67
from wcs.workflows import get_role_translation, template_on_formdata
67
from wcs.workflows import template_on_formdata
68 68

  
69 69
from .submission import FormFillPage
70 70

  
71 71

  
72 72
def geojson_formdatas(formdatas, geoloc_key='base', fields=None):
73 73
    geojson = {
74 74
        'type': 'FeatureCollection',
75 75
        'features': []
......
3180 3180
        # assigned functions
3181 3181
        if self.formdef.workflow.roles:
3182 3182
            workflow = self.formdef.workflow
3183 3183
            r += htmltext('<div id="inspect-functions" class="section">')
3184 3184
            r += htmltext('<h2>%s</h2></li>\n') % _('Functions')
3185 3185
            r += htmltext('<ul class="form-inspector biglist">')
3186 3186
            for key, label in (workflow.roles or {}).items():
3187 3187
                r += htmltext('<li><span class="label">%s</span>') % label
3188
                acting_role_id = get_role_translation(self.filled, key)
3188
                acting_role_id = self.filled.get_role_translation(key)
3189 3189
                if acting_role_id:
3190 3190
                    try:
3191 3191
                        acting_role = Role.get(acting_role_id)
3192 3192
                        r += htmltext('<div class="value"><span>%s</span></div>') % acting_role.name
3193 3193
                    except KeyError:
3194 3194
                        r += htmltext('<div class="value"><span>%s %s</span></div>') % (
3195 3195
                                acting_role_id, _('(deleted)'))
3196 3196
                else:
wcs/formdata.py
631 631
        return self.get_url(backoffice=True)
632 632

  
633 633
    def get_api_url(self):
634 634
        return '%s%s/' % (self.formdef.get_api_url(), self.id)
635 635

  
636 636
    def get_display_id(self):
637 637
        return str(self.id_display or self.id)
638 638

  
639
    def get_role_translation(self, role_name):
640
        if role_name == '_submitter':
641
            raise Exception('_submitter is not a valid role')
642
        elif str(role_name).startswith('_'):
643
            role_id = None
644
            if self.workflow_roles:
645
                role_id = self.workflow_roles.get(role_name)
646
            if not role_id and self.formdef.workflow_roles:
647
                role_id = self.formdef.workflow_roles.get(role_name)
648
            if role_id is None:
649
                return role_id
650
            return str(role_id)
651
        else:
652
            return str(role_name)
653

  
639 654
    def get_handling_role_id(self):
640 655
        # TODO: look at current status and return the role(s) actually
641 656
        # concerned by the handling of the formdata
642
        from wcs.workflows import get_role_translation
643
        return get_role_translation(self, '_receiver')
657
        return self.get_role_translation('_receiver')
644 658

  
645 659
    def get_handling_role(self):
646 660
        try:
647 661
            return Role.get(self.get_handling_role_id())
648 662
        except KeyError:
649 663
            return None
650 664

  
651 665
    def get_field_view_value(self, field, max_length=None):
......
925 939
            # drafts are only visible to submitter
926 940
            return ['_submitter']
927 941

  
928 942
        status_action_roles = set()
929 943

  
930 944
        # make sure the handling roles always gets access to the formdata, till
931 945
        # the very end (where it may be that there is no workflow status item
932 946
        # at all).
933
        from wcs.workflows import get_role_translation
934 947
        for function_key in self.formdef.workflow.roles.keys():
935
            handling_role = get_role_translation(self, function_key)
948
            handling_role = self.get_role_translation(function_key)
936 949
            if handling_role:
937 950
                status_action_roles.add(handling_role)
938 951

  
939 952
        wf_status = self.get_status()
940 953
        if not wf_status:
941 954
            status_action_roles.add('_submitter')
942 955
        else:
943 956
            status_action_roles |= set(self.get_actions_roles())
......
948 961
    def get_actions_roles(self):
949 962
        if self.is_draft():
950 963
            return []
951 964

  
952 965
        wf_status = self.get_status()
953 966
        if not wf_status:
954 967
            return []
955 968

  
956
        from wcs.workflows import get_role_translation
957 969
        status_action_roles = set()
958 970
        for item in wf_status.items or []:
959 971
            if not hasattr(item, 'by') or not item.by:
960 972
                continue
961 973
            with get_publisher().substitutions.temporary_feed(self):
962 974
                if not item.check_condition(self):
963 975
                    continue
964 976
            for role in item.by:
965 977
                if role == '_submitter':
966 978
                    status_action_roles.add(role)
967 979
                else:
968
                    real_role = get_role_translation(self, role)
980
                    real_role = self.get_role_translation(role)
969 981
                    if real_role:
970 982
                        status_action_roles.add(real_role)
971 983

  
972 984
        return status_action_roles
973 985

  
974 986
    actions_roles = property(get_actions_roles)
975 987

  
976 988
    def get_last_update_time(self):
wcs/forms/workflows.py
20 20
from quixote.directory import Directory
21 21

  
22 22
from ..qommon import errors
23 23

  
24 24
from wcs.api import get_user_from_api_query_string, is_url_signed
25 25
from wcs.roles import logged_users_role
26 26
from wcs.workflows import (
27 27
        WorkflowGlobalActionWebserviceTrigger,
28
        get_role_translation,
29 28
        perform_items)
30 29

  
31 30

  
32 31
class HookDirectory(Directory):
33 32
    _q_exports = ['']
34 33

  
35 34
    def __init__(self, formdata, action, trigger):
36 35
        self.formdata = formdata
......
47 46
        if self.trigger.roles:
48 47
            for role in self.trigger.roles:
49 48
                if role == logged_users_role().id and (user or is_url_signed()):
50 49
                    break
51 50
                if role == '_submitter' and self.formdata.is_submitter(user):
52 51
                    break
53 52
                if not user:
54 53
                    continue
55
                if get_role_translation(self.formdata, role) in user.get_roles():
54
                if self.formdata.get_role_translation(role) in user.get_roles():
56 55
                    break
57 56
            else:
58 57
                raise errors.AccessForbiddenError('insufficient roles')
59 58

  
60 59
        if hasattr(get_request(), '_json'):
61 60
            workflow_data = {self.trigger.identifier: get_request().json}
62 61
            self.formdata.update_workflow_data(workflow_data)
63 62
            self.formdata.store()
wcs/wf/aggregation_email.py
16 16

  
17 17
from ..qommon import _, N_
18 18
from ..qommon.publisher import get_publisher_class
19 19
from ..qommon.storage import StorableObject
20 20
from ..qommon.form import *
21 21
from ..qommon.cron import CronJob
22 22
from ..qommon import emails
23 23

  
24
from wcs.workflows import WorkflowStatusItem, register_item_class, \
25
        get_role_translation
24
from wcs.workflows import WorkflowStatusItem, register_item_class
26 25

  
27 26
from wcs.roles import Role
28 27

  
29 28

  
30 29
class AggregationEmailWorkflowStatusItem(WorkflowStatusItem):
31 30
    description = N_('Daily Summary Email')
32 31
    key = 'aggregationemail'
33 32
    category = 'interaction'
......
55 54
    def get_parameters(self):
56 55
        return ('to', 'condition')
57 56

  
58 57
    def perform(self, formdata):
59 58
        if not self.to:
60 59
            return
61 60

  
62 61
        for dest in self.to:
63
            dest = get_role_translation(formdata, dest)
62
            dest = formdata.get_role_translation(dest)
64 63
            try:
65 64
                aggregate = AggregationEmail.get(dest)
66 65
            except KeyError:
67 66
                aggregate = AggregationEmail(id = dest)
68 67

  
69 68
            aggregate.append({
70 69
                    'formdef': formdata.formdef.id,
71 70
                    'formdata': formdata.id,
wcs/wf/notification.py
20 20

  
21 21
from ..qommon import _, N_, ezt
22 22
from ..qommon.form import *
23 23
from ..qommon.template import TemplateError
24 24
from ..qommon import get_logger
25 25

  
26 26
from wcs.roles import Role
27 27
from wcs.workflows import (WorkflowStatusItem, register_item_class,
28
        template_on_formdata, get_role_translation)
28
        template_on_formdata)
29 29
from .wscall import WebserviceCallStatusItem
30 30

  
31 31

  
32 32
class SendNotificationWorkflowStatusItem(WebserviceCallStatusItem):
33 33
    description = N_('User Notification')
34 34
    key = 'notification'
35 35
    category = 'interaction'
36 36
    support_substitution_variables = True
......
130 130
        self.url = self.get_api_url()
131 131

  
132 132
        users = []
133 133
        for dest in self.to:
134 134
            if dest == '_submitter':
135 135
                users.append(formdata.get_user())
136 136
                continue
137 137

  
138
            dest = get_role_translation(formdata, dest)
138
            dest = formdata.get_role_translation(dest)
139 139
            try:
140 140
                role = Role.get(dest)
141 141
            except KeyError:
142 142
                continue
143 143
            users.extend(get_publisher().user_class.get_users_with_role(role.id))
144 144

  
145 145
        for user in users:
146 146
            if not user or not user.is_active:
wcs/workflows.py
500 500
            return []
501 501
        actions = []
502 502
        for action in self.global_actions or []:
503 503
            for trigger in action.triggers or []:
504 504
                if isinstance(trigger, WorkflowGlobalActionManualTrigger):
505 505
                    if '_submitter' in (trigger.roles or []) and formdata.is_submitter(user):
506 506
                        actions.append(action)
507 507
                        break
508
                    roles = [get_role_translation(formdata, x)
508
                    roles = [formdata.get_role_translation(x)
509 509
                             for x in (trigger.roles or []) if x != '_submitter']
510 510
                    if set(roles).intersection(user.get_roles()):
511 511
                        actions.append(action)
512 512
                        break
513 513
        return actions
514 514

  
515 515
    def get_subdirectories(self, formdata):
516 516
        wf_status = formdata.get_status()
......
1544 1544
                        break
1545 1545
                    if role == '_submitter':
1546 1546
                        if filled.is_submitter(user):
1547 1547
                            break
1548 1548
                        else:
1549 1549
                            continue
1550 1550
                    if user is None:
1551 1551
                        continue
1552
                    role = get_role_translation(filled, role)
1552
                    role = filled.get_role_translation(role)
1553 1553
                    if role in user.get_roles():
1554 1554
                        break
1555 1555
                else:
1556 1556
                    continue
1557 1557
            if not item.check_condition(filled):
1558 1558
                continue
1559 1559
            yield item
1560 1560

  
......
1636 1636
        visibility_roles = self.visibility[:]
1637 1637
        for item in self.items or []:
1638 1638
            if not hasattr(item, 'by') or not item.by:
1639 1639
                continue
1640 1640
            visibility_roles.extend(item.by)
1641 1641

  
1642 1642
        for role in visibility_roles:
1643 1643
            if role != '_submitter':
1644
                role = get_role_translation(formdata, role)
1644
                role = formdata.get_role_translation(role)
1645 1645
            if role in user_roles:
1646 1646
                return True
1647 1647
        return False
1648 1648

  
1649 1649
    def is_endpoint(self):
1650 1650
        # an endpoint status is a status that marks the end of the workflow; it
1651 1651
        # can either be computed automatically (if there's no way out of the
1652 1652
        # status) or be set manually (to mark the expected end while still
......
1836 1836
                return True
1837 1837
            if role == '_submitter':
1838 1838
                t = formdata.is_submitter(user)
1839 1839
                if t is True:
1840 1840
                    return True
1841 1841
                continue
1842 1842
            if not user:
1843 1843
                continue
1844
            role = get_role_translation(formdata, role)
1844
            role = formdata.get_role_translation(role)
1845 1845
            if role in user.get_roles():
1846 1846
                return True
1847 1847

  
1848 1848
        return False
1849 1849

  
1850 1850
    def check_condition(self, formdata):
1851 1851
        context = {'formdata': formdata, 'status_item': self}
1852 1852
        try:
......
2241 2241
                markers_stack = []
2242 2242
            markers_stack.append({'status_id': formdata.status[3:]})
2243 2243
            formdata.update_workflow_data({'_markers_stack': markers_stack})
2244 2244

  
2245 2245
    def get_parameters(self):
2246 2246
        return ('status', 'set_marker_on_status', 'condition')
2247 2247

  
2248 2248

  
2249
def get_role_translation(formdata, role_name):
2250
    if role_name == '_submitter':
2251
        raise Exception('_submitter is not a valid role')
2252
    elif str(role_name).startswith('_'):
2253
        role_id = None
2254
        if formdata.workflow_roles:
2255
            role_id = formdata.workflow_roles.get(role_name)
2256
        if not role_id and formdata.formdef.workflow_roles:
2257
            role_id = formdata.formdef.workflow_roles.get(role_name)
2258
        if role_id is None:
2259
            return role_id
2260
        return str(role_id)
2261
    else:
2262
        return str(role_name)
2263

  
2264

  
2265 2249
def get_role_translation_label(workflow, role_id):
2266 2250
    if role_id == logged_users_role().id:
2267 2251
        return logged_users_role().name
2268 2252
    if role_id == '_submitter':
2269 2253
        return C_('role|User')
2270 2254
    if str(role_id).startswith('_'):
2271 2255
        return workflow.roles.get(role_id)
2272 2256
    else:
......
2733 2717
                continue
2734 2718

  
2735 2719
            if dest == '_submitter':
2736 2720
                submitter_email = formdata.formdef.get_submitter_email(formdata)
2737 2721
                if submitter_email:
2738 2722
                    addresses.append(submitter_email)
2739 2723
                continue
2740 2724

  
2741
            dest = get_role_translation(formdata, dest)
2725
            dest = formdata.get_role_translation(dest)
2742 2726

  
2743 2727
            try:
2744 2728
                role = Role.get(dest)
2745 2729
            except KeyError:
2746 2730
                continue
2747 2731
            addresses.extend(role.get_emails())
2748 2732

  
2749 2733
        if not addresses:
......
2907 2891
        if not get_request():
2908 2892
            return False
2909 2893
        user = get_request().user
2910 2894
        for role in self.to or []:
2911 2895
            if role == '_submitter':
2912 2896
                if filled.is_submitter(user):
2913 2897
                    return True
2914 2898
            elif user:
2915
                role = get_role_translation(filled, role)
2899
                role = filled.get_role_translation(role)
2916 2900
                if role in user.get_roles():
2917 2901
                    return True
2918 2902
        return False
2919 2903

  
2920 2904
    def get_message(self, filled, position='top'):
2921 2905
        if not (self.message and self.position == position and self.is_for_current_user(filled)):
2922 2906
            return ''
2923 2907

  
2924
-