Projet

Général

Profil

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

Nicolas Roche, 12 décembre 2020 13:57

Télécharger (17,2 ko)

Voir les différences:

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

 wcs/backoffice/management.py |  4 ++--
 wcs/formdata.py              | 27 +++++++++++++++++++--------
 wcs/forms/workflows.py       |  3 +--
 wcs/wf/aggregation_email.py  |  5 ++---
 wcs/wf/notification.py       |  4 ++--
 wcs/wf/register_comment.py   |  2 +-
 wcs/workflows.py             | 26 +++++---------------------
 7 files changed, 32 insertions(+), 39 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
632 632
        return self.get_url(backoffice=True)
633 633

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

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

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

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

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

  
652 666
    def get_field_view_value(self, field, max_length=None):
......
910 924
    def is_submitter(self, user):
911 925
        if self.user_id and user and str(self.user_id) == str(user.id):
912 926
            return True
913 927
        if get_session() and get_session().is_anonymous_submitter(self):
914 928
            return True
915 929
        return False
916 930

  
917 931
    def is_for_current_user(self, to):
918
        from wcs.workflows import get_role_translation
919 932
        if not to:
920 933
            return True
921 934
        if not get_request():
922 935
            return False
923 936
        user = get_request().user
924 937
        for role in to or []:
925 938
            if role == '_submitter':
926 939
                if self.is_submitter(user):
927 940
                    return True
928 941
            elif user:
929
                role = get_role_translation(self, role)
942
                role = self.get_role_translation(role)
930 943
                if role in user.get_roles():
931 944
                    return True
932 945
        return False
933 946

  
934 947
    def is_draft(self, status=None):
935 948
        if status is None:
936 949
            status = self.status
937 950
        return status == 'draft'
......
941 954
            # drafts are only visible to submitter
942 955
            return ['_submitter']
943 956

  
944 957
        status_action_roles = set()
945 958

  
946 959
        # make sure the handling roles always gets access to the formdata, till
947 960
        # the very end (where it may be that there is no workflow status item
948 961
        # at all).
949
        from wcs.workflows import get_role_translation
950 962
        for function_key in self.formdef.workflow.roles.keys():
951
            handling_role = get_role_translation(self, function_key)
963
            handling_role = self.get_role_translation(function_key)
952 964
            if handling_role:
953 965
                status_action_roles.add(handling_role)
954 966

  
955 967
        wf_status = self.get_status()
956 968
        if not wf_status:
957 969
            status_action_roles.add('_submitter')
958 970
        else:
959 971
            status_action_roles |= set(self.get_actions_roles())
......
964 976
    def get_actions_roles(self):
965 977
        if self.is_draft():
966 978
            return []
967 979

  
968 980
        wf_status = self.get_status()
969 981
        if not wf_status:
970 982
            return []
971 983

  
972
        from wcs.workflows import get_role_translation
973 984
        status_action_roles = set()
974 985
        for item in wf_status.items or []:
975 986
            if not hasattr(item, 'by') or not item.by:
976 987
                continue
977 988
            with get_publisher().substitutions.temporary_feed(self):
978 989
                if not item.check_condition(self):
979 990
                    continue
980 991
            for role in item.by:
981 992
                if role == '_submitter':
982 993
                    status_action_roles.add(role)
983 994
                else:
984
                    real_role = get_role_translation(self, role)
995
                    real_role = self.get_role_translation(role)
985 996
                    if real_role:
986 997
                        status_action_roles.add(real_role)
987 998

  
988 999
        return status_action_roles
989 1000

  
990 1001
    actions_roles = property(get_actions_roles)
991 1002

  
992 1003
    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/wf/register_comment.py
17 17
from quixote import get_request
18 18

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

  
24 24
from wcs.workflows import (WorkflowStatusItem, register_item_class, template_on_formdata,
25
                           AttachmentEvolutionPart, get_role_translation)
25
                           AttachmentEvolutionPart)
26 26

  
27 27
import sys
28 28

  
29 29

  
30 30
class JournalEvolutionPart: #pylint: disable=C1001
31 31
    content = None
32 32
    to = None
33 33

  
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:
......
2242 2242
                markers_stack = []
2243 2243
            markers_stack.append({'status_id': formdata.status[3:]})
2244 2244
            formdata.update_workflow_data({'_markers_stack': markers_stack})
2245 2245

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

  
2249 2249

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

  
2265

  
2266 2250
def get_role_translation_label(workflow, role_id):
2267 2251
    if role_id == logged_users_role().id:
2268 2252
        return logged_users_role().name
2269 2253
    if role_id == '_submitter':
2270 2254
        return C_('role|User')
2271 2255
    if str(role_id).startswith('_'):
2272 2256
        return workflow.roles.get(role_id)
2273 2257
    else:
......
2735 2719
                continue
2736 2720

  
2737 2721
            if dest == '_submitter':
2738 2722
                submitter_email = formdata.formdef.get_submitter_email(formdata)
2739 2723
                if submitter_email:
2740 2724
                    addresses.append(submitter_email)
2741 2725
                continue
2742 2726

  
2743
            dest = get_role_translation(formdata, dest)
2727
            dest = formdata.get_role_translation(dest)
2744 2728

  
2745 2729
            try:
2746 2730
                role = Role.get(dest)
2747 2731
            except KeyError:
2748 2732
                continue
2749 2733
            addresses.extend(role.get_emails())
2750 2734

  
2751 2735
        if not addresses:
2752
-