Projet

Général

Profil

0001-workflows-validate-email-body-and-subject-are-correc.patch

Frédéric Péters, 13 janvier 2016 10:30

Télécharger (6,01 ko)

Voir les différences:

Subject: [PATCH] workflows: validate email body and subject are correct ezt
 strings (#9524)

 tests/test_admin_pages.py | 44 ++++++++++++++++++++++++++++++++++++++++++++
 wcs/qommon/form.py        | 24 ++++++++++++++++++++++++
 wcs/workflows.py          | 23 +++++++++++++++++++++++
 3 files changed, 91 insertions(+)
tests/test_admin_pages.py
1362 1362
    assert workflow.possible_status[0].items[0].rules == [
1363 1363
            {'value': 'FOOBAR', 'role_id': '1'}, {'value': 'BARFOO', 'role_id': '1'}]
1364 1364

  
1365
def test_workflows_edit_email_action(pub):
1366
    create_superuser(pub)
1367
    role = create_role()
1368
    Workflow.wipe()
1369
    workflow = Workflow(name='foo')
1370
    workflow.add_status(name='baz')
1371
    workflow.store()
1372

  
1373
    app = login(get_app(pub))
1374
    resp = app.get('/backoffice/workflows/1/')
1375
    resp = resp.click('baz')
1376

  
1377
    resp.forms[0]['type'] = 'Send mail'
1378
    resp = resp.forms[0].submit()
1379
    resp = resp.follow()
1380

  
1381
    resp = resp.click('Send mail')
1382
    item_url = resp.request.environ['REQUEST_URI']
1383

  
1384
    ok_strings = [
1385
        'Hello world', # ordinary string
1386
        'Hello [world]', # unknown reference
1387
        'Hello [if-any world][world][end]', # unknown reference, in condition
1388
        'Hello world ][', # random brackets
1389
    ]
1390

  
1391
    for field in ('body', 'subject'):
1392
        for ok_string in ok_strings:
1393
            resp = app.get(item_url)
1394
            resp.form[field] = ok_string
1395
            resp = resp.form.submit('submit')
1396
            assert resp.location
1397

  
1398
        resp = app.get(item_url)
1399
        resp.form[field] = 'Hello [if-any world][world][else].'
1400
        resp = resp.form.submit('submit')
1401
        assert 'error in template' in resp.body and 'unclosed block' in resp.body
1402

  
1403
        resp = app.get(item_url)
1404
        resp.form[field] = 'Hello [if-any world][world][else].[end] [end]'
1405
        resp = resp.form.submit('submit')
1406
        assert 'error in template' in resp.body and 'unmatched [end]' in resp.body
1407

  
1408

  
1365 1409
def test_workflows_variables(pub):
1366 1410
    create_superuser(pub)
1367 1411
    create_role()
wcs/qommon/form.py
439 439
        r += htmltext('</tr>\n')
440 440
        return r.getvalue()
441 441

  
442

  
443
class StringWidget(quixote.form.StringWidget):
444
    def __init__(self, name, *args, **kwargs):
445
        self.validation_function = kwargs.pop('validation_function', None)
446
        super(StringWidget, self).__init__(name, *args, **kwargs)
447

  
448
    def _parse(self, request):
449
        quixote.form.StringWidget._parse(self, request)
450
        if self.value and self.validation_function:
451
            try:
452
                self.validation_function(self.value)
453
            except ValueError as e:
454
                self.error = str(e)
455

  
456

  
442 457
class TextWidget(quixote.form.TextWidget):
458
    def __init__(self, name, *args, **kwargs):
459
        self.validation_function = kwargs.pop('validation_function', None)
460
        super(TextWidget, self).__init__(name, *args, **kwargs)
461

  
443 462
    def _parse(self, request):
444 463
        quixote.form.TextWidget._parse(self, request)
445 464
        if self.value is not None:
......
449 468
                maxlength = 0
450 469
            if maxlength and len(self.value) > maxlength:
451 470
                self.error = _('too many characters (limit is %d)') % maxlength
471
            if self.validation_function:
472
                try:
473
                    self.validation_function(self.value)
474
                except ValueError as e:
475
                    self.error = str(e)
452 476

  
453 477
class CheckboxWidget(quixote.form.CheckboxWidget):
454 478
    '''
wcs/workflows.py
1593 1593
                                        self.get_list_of_roles(include_logged_in_users=False)})
1594 1594
        if 'subject' in parameters:
1595 1595
            form.add(StringWidget, '%ssubject' % prefix, title=_('Subject'),
1596
                     validation_function=validate_ezt,
1596 1597
                     value=self.subject, size=40)
1597 1598
        if 'body' in parameters:
1598 1599
            form.add(TextWidget, '%sbody' % prefix, title=_('Body'),
1599 1600
                     value=self.body, cols=80, rows=10,
1601
                     validation_function=validate_ezt,
1600 1602
                     hint=_('Available variables: url, url_status, details, name, number, comment, field_NAME'))
1601 1603

  
1602 1604

  
......
1718 1720

  
1719 1721
    return fd.getvalue()
1720 1722

  
1723

  
1724
def validate_ezt(template):
1725
    processor = ezt.Template(compress_whitespace=False)
1726
    try:
1727
        processor.parse(template or '')
1728
    except ezt.EZTException as e:
1729
        parts = []
1730
        parts.append({
1731
            ezt.ArgCountSyntaxError: _('wrong number of arguments'),
1732
            ezt.UnknownReference: _('unknown reference'),
1733
            ezt.NeedSequenceError: _('sequence required'),
1734
            ezt.UnclosedBlocksError: _('unclosed block'),
1735
            ezt.UnmatchedEndError: _('unmatched [end]'),
1736
            ezt.BaseUnavailableError: _('unavailable base location'),
1737
            ezt.BadFormatConstantError: _('bad format constant'),
1738
            ezt.UnknownFormatConstantError: _('unknown format constant'),
1739
            }.get(e.__class__))
1740
        if e.line:
1741
            parts.append(_('at line %d and column %d') % (e.line+1, e.column+1))
1742
        raise ValueError(_('error in template (%s)') % ' '.join(parts))
1743

  
1721 1744
class SendSMSWorkflowStatusItem(WorkflowStatusItem):
1722 1745
    description = N_('Send SMS')
1723 1746
    key = 'sendsms'
1724
-