Projet

Général

Profil

0001-backoffice-use-a-customisable-template-to-render-use.patch

Frédéric Péters, 20 mai 2020 11:38

Télécharger (12,4 ko)

Voir les différences:

Subject: [PATCH] backoffice: use a customisable template to render user info
 in sidebar (#40034)

 tests/test_admin_pages.py      | 53 ++++++++++++++++++++++--------
 tests/test_backoffice_pages.py | 26 +++++++++++++++
 wcs/admin/settings.py          | 59 +++++++++++++++++++++++++++++++---
 wcs/backoffice/management.py   | 12 ++++++-
 4 files changed, 131 insertions(+), 19 deletions(-)
tests/test_admin_pages.py
4727 4727
    resp = app.get('/backoffice/settings/users').follow().follow()
4728 4728

  
4729 4729
    # add a field
4730
    resp.forms[1]['label'] = 'foobar'
4731
    resp = resp.forms[1].submit()
4730
    resp.forms[2]['label'] = 'foobar'
4731
    resp = resp.forms[2].submit()
4732 4732
    assert resp.location == 'http://example.net/backoffice/settings/users/fields/'
4733 4733
    resp = resp.follow()
4734 4734
    assert b'foobar' in pub.cfg['users']['formdef']
4735 4735
    assert 'foobar' in resp.text
4736 4736

  
4737 4737
    # set field as email
4738
    resp.forms[0]['field_email'] = '1'
4739
    resp = resp.forms[0].submit()
4738
    resp.forms['mapping']['field_email'] = '1'
4739
    resp = resp.forms['mapping'].submit()
4740 4740
    assert resp.location == 'http://example.net/backoffice/settings/users/fields/'
4741 4741
    resp = resp.follow()
4742 4742
    assert pub.cfg['users']['field_email'] == '1'
4743 4743

  
4744 4744
    # and unset it
4745
    resp.forms[0]['field_email'] = ''
4746
    resp = resp.forms[0].submit()
4745
    resp.forms['mapping']['field_email'] = ''
4746
    resp = resp.forms['mapping'].submit()
4747 4747
    assert resp.location == 'http://example.net/backoffice/settings/users/fields/'
4748 4748
    resp = resp.follow()
4749 4749
    assert pub.cfg['users']['field_email'] == None
4750 4750

  
4751 4751
    # add a comment field
4752
    resp.forms[1]['label'] = 'barfoo'
4753
    resp.forms[1]['type'] = 'Comment'
4754
    resp = resp.forms[1].submit()
4752
    resp.forms[2]['label'] = 'barfoo'
4753
    resp.forms[2]['type'] = 'Comment'
4754
    resp = resp.forms[2].submit()
4755 4755
    assert resp.location == 'http://example.net/backoffice/settings/users/fields/'
4756 4756
    resp = resp.follow()
4757 4757
    assert b'barfoo' in pub.cfg['users']['formdef']
......
4760 4760
    # check fields are present in edit form
4761 4761
    resp = app.get('/backoffice/users/%s/edit' % user.id)
4762 4762
    assert 'barfoo' in resp.text
4763
    assert 'f1' in resp.forms[0].fields
4764
    assert 'email' in resp.forms[0].fields
4763
    assert 'f1' in resp.form.fields
4764
    assert 'email' in resp.form.fields
4765 4765

  
4766 4766
    # check the email field is not displayed if it's overridden by a custom
4767 4767
    # field.
4768 4768
    pub.cfg['users']['field_email'] = '1'
4769 4769
    pub.write_cfg()
4770 4770
    resp = app.get('/backoffice/users/%s/edit' % user.id)
4771
    assert 'f1' in resp.forms[0].fields
4772
    assert 'email' not in resp.forms[0].fields
4771
    assert 'f1' in resp.form.fields
4772
    assert 'email' not in resp.form.fields
4773

  
4774
    # set a sidebar template
4775
    app = login(get_app(pub))
4776
    resp = app.get('/backoffice/settings/users').follow().follow()
4777
    resp.forms['template']['sidebar_template'] = 'hello {{ form_user_display_name }}'
4778
    resp = resp.forms['template'].submit().follow()
4779
    assert pub.cfg['users']['sidebar_template'] == 'hello {{ form_user_display_name }}'
4780
    resp.forms['template']['sidebar_template'] = '{% if True %}'
4781
    resp = resp.forms['template'].submit().follow()
4782
    assert pub.cfg['users']['sidebar_template'] == 'hello {{ form_user_display_name }}'
4783
    assert 'syntax error in Django template' in resp
4784

  
4785
    # disable users screen
4786
    if not pub.site_options.has_section('options'):
4787
        pub.site_options.add_section('options')
4788
    pub.site_options.set('options', 'settings-disabled-screens', 'users')
4789
    with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
4790
        pub.site_options.write(fd)
4791

  
4792
    resp = app.get('/backoffice/settings/')
4793
    resp = resp.click('Users', href='user-template')
4794
    resp.forms['template']['sidebar_template'] = '{% if True %}'
4795
    resp = resp.forms['template'].submit()
4796
    assert 'syntax error in Django template' in resp
4797
    resp.forms['template']['sidebar_template'] = 'hello {{ form_user_display_name }}'
4798
    resp = resp.forms['template'].submit()
4799
    assert pub.cfg['users']['sidebar_template'] == 'hello {{ form_user_display_name }}'
4773 4800

  
4774 4801
    # restore config
4775 4802
    pub.cfg['users']['field_email'] = None
tests/test_backoffice_pages.py
1913 1913
    assert 'by %s' % user.get_display_name() in resp.text
1914 1914

  
1915 1915

  
1916
def test_backoffice_sidebar_user_template(pub):
1917
    user = create_user(pub)
1918
    create_environment(pub)
1919
    form_class = FormDef.get_by_urlname('form-title').data_class()
1920
    number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
1921
    number31.user_id = user.id
1922
    number31.store()
1923
    app = login(get_app(pub))
1924
    resp = app.get('/backoffice/management/form-title/')
1925
    resp = resp.click(href='%s/' % number31.id)
1926
    assert 'Associated User' in resp.text
1927
    assert '<p>admin</p>' in resp.text
1928
    pub.cfg['users'] = {'sidebar_template': 'XXX{{ form_user_display_name }}YYY'}
1929
    pub.write_cfg()
1930
    resp = app.get(resp.request.url)
1931
    assert '<p>XXXadminYYY</p>' in resp.text
1932
    pub.cfg['users'] = {'sidebar_template': 'XXX<b>{{ form_user_display_name }}</b>YYY'}
1933
    pub.write_cfg()
1934
    resp = app.get(resp.request.url)
1935
    assert '<p>XXX<b>admin</b>YYY</p>' in resp.text
1936
    user.name = 'adm<i>n'
1937
    user.store()
1938
    resp = app.get(resp.request.url)
1939
    assert '<p>XXX<b>adm&lt;i&gt;n</b>YYY</p>' in resp.text
1940

  
1941

  
1916 1942
def test_backoffice_geolocation_info(pub):
1917 1943
    user = create_user(pub)
1918 1944
    create_environment(pub)
wcs/admin/settings.py
118 118

  
119 119

  
120 120
class UserFieldsDirectory(FieldsDirectory):
121
    _q_exports = ['', 'update_order', 'new', 'mapping']
121
    _q_exports = ['', 'update_order', 'new', 'mapping', 'template']
122 122

  
123 123
    section = 'settings'
124 124
    field_def_page_class = UserFieldDefPage
......
128 128

  
129 129
    def index_bottom(self):
130 130
        r = TemplateIO(html=True)
131
        r += get_session().display_message()
131 132
        r += htmltext('<div class="bo-block">')
132 133
        r += htmltext('<h2>%s</h2>') % _('Fields Mapping')
133 134
        r += htmltext('<p>%s</p>') % _('These settings make it possible to assign custom user fields to standard user fields.')
134
        form = self.mapping_form()
135
        r += form.render()
135
        r += self.mapping_form().render()
136
        r += htmltext('</div>')
137
        r += htmltext('<div class="bo-block">')
138
        r += htmltext('<h2>%s</h2>') % _('Sidebar Template')
139
        r += self.sidebar_template_form().render()
136 140
        r += htmltext('</div>')
137 141
        return r.getvalue()
138 142

  
......
141 145
        options = [(None, _('None'), '')] + [
142 146
                (x.id, x.label, x.id) for x in self.objectdef.fields]
143 147

  
144
        form = Form(action = 'mapping', enctype='multipart/form-data')
148
        form = Form(action='mapping', id='mapping')
145 149
        field_name_value = users_cfg.get('field_name')
146 150
        if type(field_name_value) is str:
147 151
            field_name_value = [field_name_value]
......
161 165
        cfg_submit(form, 'users', ['field_name', 'field_email'])
162 166
        return redirect('.')
163 167

  
168
    @classmethod
169
    def sidebar_template_form(cls, action='template'):
170
        users_cfg = get_cfg('users', {})
171
        form = Form(action=action, id='template')
172
        form.add(TextWidget, 'sidebar_template',
173
                value=users_cfg.get('sidebar_template') or '{{ form_user_display_name }}',
174
                required=False,
175
                validation_function=ComputedExpressionWidget.validate_template,
176
                rows=4)
177
        form.add_submit('submit', _('Submit'))
178
        return form
179

  
180
    def template(self):
181
        form = self.sidebar_template_form()
182
        if form.has_errors():
183
            get_session().message = ('error', form.get_widget('sidebar_template').get_error())
184
            return redirect('.')
185
        cfg_submit(form, 'users', ['sidebar_template'])
186
        return redirect('.')
187

  
164 188

  
165 189
class UserFieldsFormDef(FormDef):
166 190
    '''Class to handle custom user fields, it loads and saves from/to
......
405 429
            'session', 'download_theme', 'smstest', 'postgresql',
406 430
            ('admin-permissions', 'admin_permissions'), 'geolocation',
407 431
            'theme_preview', 'filetypes',
432
            ('user-template', 'user_template'),
408 433
            ('data-sources', 'data_sources'), 'wscalls', 'logs']
409 434

  
410 435
    emails = EmailsDirectory()
......
514 539
        if enabled('geolocation'):
515 540
            r += htmltext('<dt><a href="geolocation">%s</a></dt> <dd>%s</dd>') % (
516 541
                    _('Geolocation'), _('Configure geolocation'))
517
        if enabled('users'):
542
        if False and enabled('users'):
518 543
            r += htmltext('<dt><a href="users/">%s</a></dt> <dd>%s</dd>') % (
519 544
                    _('Users'), _('Configure users'))
545
        else:
546
            # minimal options
547
            r += htmltext('<dt><a href="user-template">%s</a></dt> <dd>%s</dd>') % (
548
                    _('Users'), _('Configure sidebar template for users'))
520 549
        if enabled('emails'):
521 550
            r += htmltext('<dt><a href="emails/">%s</a></dt> <dd>%s</dd>') % (
522 551
                    _('Emails'), _('Configure email settings'))
......
1223 1252
        r += htmltext('<h2>%s</h2>') % _('Geolocation Settings')
1224 1253
        r += form.render()
1225 1254
        return r.getvalue()
1255

  
1256
    def user_template(self):
1257
        users_cfg = get_cfg('users', {})
1258
        form = UserFieldsDirectory.sidebar_template_form(action='user-template')
1259
        form.get_widget('sidebar_template').set_title(_('Sidebar Template'))
1260
        form.add_submit('cancel', _('Cancel'))
1261

  
1262
        if form.get_widget('cancel').parse():
1263
            return redirect('.')
1264

  
1265
        if form.is_submitted() and not form.has_errors():
1266
            cfg_submit(form, 'users', ['sidebar_template'])
1267
            return redirect('.')
1268

  
1269
        get_response().breadcrumb.append(('user-template', _('Users')))
1270
        html_top('settings', title=_('Users'))
1271
        r = TemplateIO(html=True)
1272
        r += htmltext('<h2>%s</h2>') % _('Users')
1273
        r += form.render()
1274
        return r.getvalue()
wcs/backoffice/management.py
53 53
from ..qommon.form import *
54 54
from ..qommon.storage import (Equal, NotEqual, LessOrEqual, GreaterOrEqual, Or,
55 55
        Intersects, ILike, FtsMatch, Contains, Null, NotNull)
56
from ..qommon.template import Template
56 57

  
57 58
from wcs.api_utils import get_user_from_api_query_string
58 59
from wcs.carddef import CardDef
......
2661 2662
        if formdata.user_id and formdata.get_user():
2662 2663
            r += htmltext('<div class="extra-context">')
2663 2664
            r += htmltext('<h3>%s</h3>') % _('Associated User')
2664
            r += htmltext('<p>%s</p>') % formdata.get_user().display_name
2665
            users_cfg = get_cfg('users', {})
2666
            sidebar_user_template = users_cfg.get('sidebar_template')
2667
            if sidebar_user_template:
2668
                variables = get_publisher().substitutions.get_context_variables(mode='lazy')
2669
                sidebar_user = Template(sidebar_user_template).render(variables)
2670
                if not sidebar_user.startswith('<'):
2671
                    sidebar_user = htmltext('<p>%s</p>' % sidebar_user)
2672
                r += sidebar_user
2673
            else:
2674
                r += htmltext('<p>%s</p>') % formdata.get_user().display_name
2665 2675
            r += htmltext('</div>')
2666 2676

  
2667 2677
        if formdata.formdef.geolocations and formdata.geolocations:
2668
-