Projet

Général

Profil

0001-misc-split-file-field-tests-54131.patch

Lauréline Guérin, 16 septembre 2021 15:02

Télécharger (25,6 ko)

Voir les différences:

Subject: [PATCH 1/2] misc: split file field tests (#54131)

 tests/form_pages/test_all.py        | 313 -----------------------
 tests/form_pages/test_file_field.py | 377 ++++++++++++++++++++++++++++
 2 files changed, 377 insertions(+), 313 deletions(-)
 create mode 100644 tests/form_pages/test_file_field.py
tests/form_pages/test_all.py
3339 3339
    assert 'form_captcha' in resp.text
3340 3340

  
3341 3341

  
3342
def test_form_file_field_with_fargo(pub, fargo_url):
3343
    create_user(pub)
3344
    formdef = create_formdef()
3345
    file_field = fields.FileField(id='0', label='file')
3346
    assert file_field.allow_portfolio_picking is False
3347
    file_field.allow_portfolio_picking = True
3348
    formdef.fields = [file_field]
3349
    formdef.store()
3350
    formdef.data_class().wipe()
3351

  
3352
    assert file_field.allow_portfolio_picking is True
3353

  
3354
    resp = get_app(pub).get('/test/')
3355
    assert 'f0$file' in resp.text
3356
    assert 'fargo.js' not in resp.text
3357
    assert 'use-file-from-fargo' not in resp.text
3358

  
3359
    app = get_app(pub)
3360
    login(app, username='foo', password='foo')
3361
    resp = app.get('/test/')
3362
    assert 'f0$file' in resp.text
3363
    assert 'fargo.js' in resp.text
3364
    assert 'use-file-from-fargo' in resp.text
3365

  
3366
    fargo_resp = app.get('/fargo/pick')  # display file picker
3367
    assert fargo_resp.location == 'http://fargo.example.net/pick/?pick=http%3A//example.net/fargo/pick'
3368
    with mock.patch('wcs.portfolio.urlopen') as urlopen:
3369
        urlopen.side_effect = lambda *args: io.BytesIO(b'...')
3370
        fargo_resp = app.get('/fargo/pick?url=http://www.example.org/...')
3371
        assert 'window.top.document.fargo_set_token' in fargo_resp.text
3372
    resp.form['f0$file'] = None
3373
    resp.form['f0$token'] = re.findall(r'fargo_set_token\("(.*?)"', fargo_resp.text)[0]
3374
    resp = resp.form.submit('submit')
3375
    assert 'Check values then click submit.' in resp.text
3376
    resp = resp.form.submit('submit')
3377
    assert formdef.data_class().count() == 1
3378
    formdata = formdef.data_class().select()[0]
3379
    assert formdata.data['0'].get_content() == b'...'
3380

  
3381
    file_field.allow_portfolio_picking = False
3382
    formdef.store()
3383

  
3384
    resp = login(get_app(pub), username='foo', password='foo').get('/test/')
3385
    assert 'f0$file' in resp.text
3386
    assert 'fargo.js' not in resp.text
3387
    assert 'use-file-from-fargo' not in resp.text
3388

  
3389

  
3390
def test_form_file_field_without_fargo(pub):
3391
    create_user(pub)
3392
    formdef = create_formdef()
3393
    file_field = fields.FileField(id='0', label='file')
3394
    file_field.allow_portfolio_picking = True
3395
    formdef.fields = [file_field]
3396
    formdef.store()
3397
    formdef.data_class().wipe()
3398

  
3399
    assert file_field.allow_portfolio_picking is True
3400

  
3401
    resp = get_app(pub).get('/test/')
3402
    assert 'f0$file' in resp.text
3403
    assert 'fargo.js' not in resp.text
3404
    assert 'use-file-from-fargo' not in resp.text
3405

  
3406
    resp = login(get_app(pub), username='foo', password='foo').get('/test/')
3407
    assert 'f0$file' in resp.text
3408
    assert 'fargo.js' not in resp.text
3409
    assert 'use-file-from-fargo' not in resp.text
3410

  
3411

  
3412
def test_form_file_field_submit(pub):
3413
    formdef = create_formdef()
3414
    formdef.fields = [fields.FileField(id='0', label='file')]
3415
    formdef.store()
3416
    formdef.data_class().wipe()
3417

  
3418
    upload = Upload('test.txt', b'foobar', 'text/plain')
3419

  
3420
    resp = get_app(pub).get('/test/')
3421
    resp.forms[0]['f0$file'] = upload
3422
    resp = resp.forms[0].submit('submit')
3423
    assert 'Check values then click submit.' in resp.text
3424
    resp = resp.forms[0].submit('submit')
3425
    assert resp.status_int == 302
3426
    resp = resp.follow()
3427
    assert 'The form has been recorded' in resp.text
3428
    resp = resp.click('test.txt')
3429
    assert resp.location.endswith('/test.txt')
3430
    resp = resp.follow()
3431
    assert resp.content_type == 'text/plain'
3432
    assert resp.text == 'foobar'
3433

  
3434

  
3435
def test_form_preupload_file_field_submit(pub):
3436
    formdef = create_formdef()
3437
    formdef.fields = [fields.FileField(id='0', label='file')]
3438
    formdef.store()
3439
    formdef.data_class().wipe()
3440

  
3441
    app = get_app(pub)
3442

  
3443
    resp = app.get('/test/')
3444
    upload = Upload('test.txt', b'foobar', 'text/plain')
3445
    resp.form['f0$file'] = upload
3446

  
3447
    # this part is actually done in javascript
3448
    upload_url = resp.form['f0$file'].attrs['data-url']
3449
    upload_resp = app.post(upload_url, params=resp.form.submit_fields())
3450
    resp.form['f0$file'] = None
3451
    resp.form['f0$token'] = upload_resp.json[0]['token']
3452

  
3453
    resp = resp.forms[0].submit('submit')
3454
    assert 'Check values then click submit.' in resp.text
3455
    resp = resp.forms[0].submit('submit')
3456
    assert resp.status_int == 302
3457
    resp = resp.follow()
3458
    assert 'The form has been recorded' in resp.text
3459
    resp = resp.click('test.txt')
3460
    assert resp.location.endswith('/test.txt')
3461
    resp = resp.follow()
3462
    assert resp.content_type == 'text/plain'
3463
    assert resp.text == 'foobar'
3464

  
3465
    # upload error if file storage is unknown (out of order)
3466
    formdef.fields[0].storage = 'unknown-storage'
3467
    formdef.store()
3468
    resp = app.get('/test/')
3469
    resp.form['f0$file'] = upload
3470
    # javascript simulation
3471
    upload_url = resp.form['f0$file'].attrs['data-url']
3472
    upload_resp = app.post(upload_url, params=resp.form.submit_fields())
3473
    assert upload_resp.json == [{'error': 'failed to store file (system error)'}]
3474
    # try to post the form anyway (with file in f0$file, i.e. "no javascript")
3475
    resp = resp.forms[0].submit('submit')
3476
    assert 'Check values then click submit.' not in resp.text
3477
    assert 'failed to store file (system error)' in resp.text
3478

  
3479

  
3480
def test_form_file_field_image_submit(pub):
3481
    formdef = create_formdef()
3482
    formdef.fields = [fields.FileField(id='0', label='file')]
3483
    formdef.store()
3484
    formdef.data_class().wipe()
3485

  
3486
    with open(os.path.join(os.path.dirname(__file__), '..', 'image-with-gps-data.jpeg'), 'rb') as fd:
3487
        image_content = fd.read()
3488
    upload = Upload('test.jpg', image_content, 'image/jpeg')
3489

  
3490
    app = get_app(pub)
3491
    resp = app.get('/test/')
3492
    resp.forms[0]['f0$file'] = upload
3493
    resp = resp.forms[0].submit('submit')
3494
    assert 'Check values then click submit.' in resp.text
3495
    assert '<img alt="" src="tempfile?' in resp.text
3496
    tempfile_id = resp.text[resp.text.index('tempfile?') :].split('&', 1)[0].split('=')[1]
3497

  
3498
    resp_tempfile = app.get('/test/tempfile?t=%s' % tempfile_id)
3499
    assert resp_tempfile.body == image_content
3500

  
3501
    if Image:
3502
        # check thumbnailing of image in validation page
3503
        resp_thumbnail = app.get('/test/tempfile?t=%s&thumbnail=1' % tempfile_id)
3504
        assert resp_thumbnail.content_type == 'image/png'
3505

  
3506
    resp = resp.form.submit('submit').follow()
3507
    assert '<img ' in resp.text
3508
    assert 'download?f=0&thumbnail=1' in resp.text
3509
    resp = resp.goto('download?f=0&thumbnail=1')
3510
    assert '/thumbnail/' in resp.location
3511
    resp = resp.follow()
3512
    if Image:
3513
        # check thumbnailing of image in submitted form
3514
        assert resp.content_type == 'image/png'
3515

  
3516
        # check a fake image is not sent back
3517
        upload = Upload('test.jpg', b'<script>evil javascript</script>', 'image/jpeg')
3518
        app = get_app(pub)
3519
        resp = app.get('/test/')
3520
        resp.forms[0]['f0$file'] = upload
3521
        resp = resp.forms[0].submit('submit')
3522
        assert '<img alt="" src="tempfile?' not in resp.text
3523

  
3524

  
3525
def test_form_file_field_submit_document_type(pub):
3526
    formdef = create_formdef()
3527
    formdef.fields = [
3528
        fields.FileField(
3529
            id='0',
3530
            label='file',
3531
            document_type={
3532
                'id': 1,
3533
                'mimetypes': ['image/*'],
3534
                'label': 'Image files',
3535
            },
3536
        )
3537
    ]
3538
    formdef.store()
3539
    formdef.data_class().wipe()
3540

  
3541
    upload = Upload('test.txt', b'foobar', 'application/force-download')
3542

  
3543
    resp = get_app(pub).get('/test/')
3544
    resp.form['f0$file'] = upload
3545
    resp = resp.form.submit('submit')
3546
    assert 'invalid file type' in resp.text
3547

  
3548
    with open(os.path.join(os.path.dirname(__file__), '..', 'image-with-gps-data.jpeg'), 'rb') as fd:
3549
        image_content = fd.read()
3550
    upload = Upload('test.jpg', image_content, 'image/jpeg')
3551
    resp = get_app(pub).get('/test/')
3552
    resp.form['f0$file'] = upload
3553
    resp = resp.form.submit('submit')
3554
    assert 'Check values then click submit.' in resp.text
3555

  
3556

  
3557
def test_form_file_field_submit_max_file_size(pub):
3558
    formdef = create_formdef()
3559
    formdef.fields = [fields.FileField(id='0', label='file', max_file_size='1ko')]
3560
    formdef.store()
3561
    formdef.data_class().wipe()
3562

  
3563
    upload = Upload('test.txt', b'foobar' * 1000, 'application/force-download')
3564
    resp = get_app(pub).get('/test/')
3565
    resp.form['f0$file'] = upload
3566
    resp = resp.form.submit('submit')
3567
    assert 'over file size limit (1ko)' in resp.text
3568

  
3569
    upload = Upload('test.txt', b'foobar' * 100, 'application/force-download')
3570
    resp = get_app(pub).get('/test/')
3571
    resp.form['f0$file'] = upload
3572
    resp = resp.form.submit('submit')
3573
    assert 'Check values then click submit.' in resp.text
3574

  
3575

  
3576
def test_form_file_field_submit_wrong_mimetype(pub):
3577
    formdef = create_formdef()
3578
    formdef.fields = [fields.FileField(id='0', label='file')]
3579
    formdef.store()
3580
    formdef.data_class().wipe()
3581

  
3582
    upload = Upload('test.txt', b'foobar', 'application/force-download')
3583

  
3584
    resp = get_app(pub).get('/test/')
3585
    resp.forms[0]['f0$file'] = upload
3586
    resp = resp.forms[0].submit('submit')
3587
    assert 'Check values then click submit.' in resp.text
3588
    resp = resp.forms[0].submit('submit')
3589
    assert resp.status_int == 302
3590
    resp = resp.follow()
3591
    assert 'The form has been recorded' in resp.text
3592
    resp = resp.click('test.txt')
3593
    assert resp.location.endswith('/test.txt')
3594
    resp = resp.follow()
3595
    assert resp.content_type == 'text/plain'
3596
    assert resp.text == 'foobar'
3597

  
3598
    upload = Upload('test.pdf', b'%PDF-1.4 ...', 'application/force-download')
3599

  
3600
    resp = get_app(pub).get('/test/')
3601
    resp.forms[0]['f0$file'] = upload
3602
    resp = resp.forms[0].submit('submit')
3603
    assert 'Check values then click submit.' in resp.text
3604
    resp = resp.forms[0].submit('submit')
3605
    assert resp.status_int == 302
3606
    resp = resp.follow()
3607
    assert 'The form has been recorded' in resp.text
3608
    resp = resp.click('test.pdf')
3609
    assert resp.location.endswith('/test.pdf')
3610
    resp = resp.follow()
3611
    assert resp.content_type == 'application/pdf'
3612
    assert resp.text == '%PDF-1.4 ...'
3613

  
3614

  
3615
def test_form_file_field_submit_blacklist(pub):
3616
    formdef = create_formdef()
3617
    formdef.fields = [fields.FileField(id='0', label='file')]
3618
    formdef.store()
3619
    formdef.data_class().wipe()
3620

  
3621
    # application/x-ms-dos-executable
3622
    upload = Upload('test.exe', b'MZ...', 'application/force-download')
3623
    resp = get_app(pub).get('/test/')
3624
    resp.forms[0]['f0$file'] = upload
3625
    resp = resp.forms[0].submit('submit')
3626
    assert 'forbidden file type' in resp.text
3627

  
3628
    # define custom blacklist
3629
    pub.load_site_options()
3630
    if not pub.site_options.has_section('options'):
3631
        pub.site_options.add_section('options')
3632
    pub.site_options.set('options', 'blacklisted-file-types', 'application/pdf')
3633
    with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
3634
        pub.site_options.write(fd)
3635

  
3636
    # check against mime type
3637
    upload = Upload('test.pdf', b'%PDF-1.4 ...', 'application/force-download')
3638
    resp = get_app(pub).get('/test/')
3639
    resp.forms[0]['f0$file'] = upload
3640
    resp = resp.forms[0].submit('submit')
3641
    assert 'forbidden file type' in resp.text
3642

  
3643
    # check against extension
3644
    pub.site_options.set('options', 'blacklisted-file-types', '.pdf')
3645
    with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
3646
        pub.site_options.write(fd)
3647

  
3648
    upload = Upload('test.pdf', b'%PDF-1.4 ...', 'application/force-download')
3649
    resp = get_app(pub).get('/test/')
3650
    resp.forms[0]['f0$file'] = upload
3651
    resp = resp.forms[0].submit('submit')
3652
    assert 'forbidden file type' in resp.text
3653

  
3654

  
3655 3342
def test_form_table_field_submit(pub, emails):
3656 3343
    formdef = create_formdef()
3657 3344
    formdef.fields = [
tests/form_pages/test_file_field.py
1
import io
2
import os
3
import re
4
from unittest import mock
5

  
6
import pytest
7
from webtest import Upload
8

  
9
try:
10
    from PIL import Image
11
except ImportError:
12
    Image = None
13

  
14
from wcs import fields
15
from wcs.categories import Category
16
from wcs.formdef import FormDef
17

  
18
from ..utilities import clean_temporary_pub, create_temporary_pub, get_app, login
19
from .test_all import create_user
20

  
21

  
22
def pytest_generate_tests(metafunc):
23
    if 'pub' in metafunc.fixturenames:
24
        metafunc.parametrize('pub', ['pickle', 'sql', 'pickle-templates', 'pickle-lazy'], indirect=True)
25

  
26

  
27
@pytest.fixture
28
def pub(request):
29
    pub = create_temporary_pub(
30
        sql_mode=bool('sql' in request.param),
31
        templates_mode=bool('templates' in request.param),
32
        lazy_mode=bool('lazy' in request.param),
33
    )
34
    pub.cfg['identification'] = {'methods': ['password']}
35
    pub.cfg['language'] = {'language': 'en'}
36
    pub.write_cfg()
37

  
38
    if Category.count() == 0:
39
        cat = Category(name='foobar')
40
        cat.store()
41

  
42
    return pub
43

  
44

  
45
def teardown_module(module):
46
    clean_temporary_pub()
47

  
48

  
49
def test_form_file_field_with_fargo(pub, fargo_url):
50
    create_user(pub)
51
    FormDef.wipe()
52
    formdef = FormDef()
53
    formdef.name = 'test'
54
    file_field = fields.FileField(id='0', label='file')
55
    assert file_field.allow_portfolio_picking is False
56
    file_field.allow_portfolio_picking = True
57
    formdef.fields = [file_field]
58
    formdef.store()
59
    formdef.data_class().wipe()
60

  
61
    assert file_field.allow_portfolio_picking is True
62

  
63
    resp = get_app(pub).get('/test/')
64
    assert 'f0$file' in resp.text
65
    assert 'fargo.js' not in resp.text
66
    assert 'use-file-from-fargo' not in resp.text
67

  
68
    app = get_app(pub)
69
    login(app, username='foo', password='foo')
70
    resp = app.get('/test/')
71
    assert 'f0$file' in resp.text
72
    assert 'fargo.js' in resp.text
73
    assert 'use-file-from-fargo' in resp.text
74

  
75
    fargo_resp = app.get('/fargo/pick')  # display file picker
76
    assert fargo_resp.location == 'http://fargo.example.net/pick/?pick=http%3A//example.net/fargo/pick'
77
    with mock.patch('wcs.portfolio.urlopen') as urlopen:
78
        urlopen.side_effect = lambda *args: io.BytesIO(b'...')
79
        fargo_resp = app.get('/fargo/pick?url=http://www.example.org/...')
80
        assert 'window.top.document.fargo_set_token' in fargo_resp.text
81
    resp.form['f0$file'] = None
82
    resp.form['f0$token'] = re.findall(r'fargo_set_token\("(.*?)"', fargo_resp.text)[0]
83
    resp = resp.form.submit('submit')
84
    assert 'Check values then click submit.' in resp.text
85
    resp = resp.form.submit('submit')
86
    assert formdef.data_class().count() == 1
87
    formdata = formdef.data_class().select()[0]
88
    assert formdata.data['0'].get_content() == b'...'
89

  
90
    file_field.allow_portfolio_picking = False
91
    formdef.store()
92

  
93
    resp = login(get_app(pub), username='foo', password='foo').get('/test/')
94
    assert 'f0$file' in resp.text
95
    assert 'fargo.js' not in resp.text
96
    assert 'use-file-from-fargo' not in resp.text
97

  
98

  
99
def test_form_file_field_without_fargo(pub):
100
    create_user(pub)
101
    FormDef.wipe()
102
    formdef = FormDef()
103
    formdef.name = 'test'
104
    file_field = fields.FileField(id='0', label='file')
105
    file_field.allow_portfolio_picking = True
106
    formdef.fields = [file_field]
107
    formdef.store()
108
    formdef.data_class().wipe()
109

  
110
    assert file_field.allow_portfolio_picking is True
111

  
112
    resp = get_app(pub).get('/test/')
113
    assert 'f0$file' in resp.text
114
    assert 'fargo.js' not in resp.text
115
    assert 'use-file-from-fargo' not in resp.text
116

  
117
    resp = login(get_app(pub), username='foo', password='foo').get('/test/')
118
    assert 'f0$file' in resp.text
119
    assert 'fargo.js' not in resp.text
120
    assert 'use-file-from-fargo' not in resp.text
121

  
122

  
123
def test_form_file_field_submit(pub):
124
    FormDef.wipe()
125
    formdef = FormDef()
126
    formdef.name = 'test'
127
    formdef.fields = [fields.FileField(id='0', label='file')]
128
    formdef.store()
129
    formdef.data_class().wipe()
130

  
131
    upload = Upload('test.txt', b'foobar', 'text/plain')
132

  
133
    resp = get_app(pub).get('/test/')
134
    resp.forms[0]['f0$file'] = upload
135
    resp = resp.forms[0].submit('submit')
136
    assert 'Check values then click submit.' in resp.text
137
    resp = resp.forms[0].submit('submit')
138
    assert resp.status_int == 302
139
    resp = resp.follow()
140
    assert 'The form has been recorded' in resp.text
141
    resp = resp.click('test.txt')
142
    assert resp.location.endswith('/test.txt')
143
    resp = resp.follow()
144
    assert resp.content_type == 'text/plain'
145
    assert resp.text == 'foobar'
146

  
147

  
148
def test_form_preupload_file_field_submit(pub):
149
    FormDef.wipe()
150
    formdef = FormDef()
151
    formdef.name = 'test'
152
    formdef.fields = [fields.FileField(id='0', label='file')]
153
    formdef.store()
154
    formdef.data_class().wipe()
155

  
156
    app = get_app(pub)
157

  
158
    resp = app.get('/test/')
159
    upload = Upload('test.txt', b'foobar', 'text/plain')
160
    resp.form['f0$file'] = upload
161

  
162
    # this part is actually done in javascript
163
    upload_url = resp.form['f0$file'].attrs['data-url']
164
    upload_resp = app.post(upload_url, params=resp.form.submit_fields())
165
    resp.form['f0$file'] = None
166
    resp.form['f0$token'] = upload_resp.json[0]['token']
167

  
168
    resp = resp.forms[0].submit('submit')
169
    assert 'Check values then click submit.' in resp.text
170
    resp = resp.forms[0].submit('submit')
171
    assert resp.status_int == 302
172
    resp = resp.follow()
173
    assert 'The form has been recorded' in resp.text
174
    resp = resp.click('test.txt')
175
    assert resp.location.endswith('/test.txt')
176
    resp = resp.follow()
177
    assert resp.content_type == 'text/plain'
178
    assert resp.text == 'foobar'
179

  
180
    # upload error if file storage is unknown (out of order)
181
    formdef.fields[0].storage = 'unknown-storage'
182
    formdef.store()
183
    resp = app.get('/test/')
184
    resp.form['f0$file'] = upload
185
    # javascript simulation
186
    upload_url = resp.form['f0$file'].attrs['data-url']
187
    upload_resp = app.post(upload_url, params=resp.form.submit_fields())
188
    assert upload_resp.json == [{'error': 'failed to store file (system error)'}]
189
    # try to post the form anyway (with file in f0$file, i.e. "no javascript")
190
    resp = resp.forms[0].submit('submit')
191
    assert 'Check values then click submit.' not in resp.text
192
    assert 'failed to store file (system error)' in resp.text
193

  
194

  
195
def test_form_file_field_image_submit(pub):
196
    FormDef.wipe()
197
    formdef = FormDef()
198
    formdef.name = 'test'
199
    formdef.fields = [fields.FileField(id='0', label='file')]
200
    formdef.store()
201
    formdef.data_class().wipe()
202

  
203
    with open(os.path.join(os.path.dirname(__file__), '..', 'image-with-gps-data.jpeg'), 'rb') as fd:
204
        image_content = fd.read()
205
    upload = Upload('test.jpg', image_content, 'image/jpeg')
206

  
207
    app = get_app(pub)
208
    resp = app.get('/test/')
209
    resp.forms[0]['f0$file'] = upload
210
    resp = resp.forms[0].submit('submit')
211
    assert 'Check values then click submit.' in resp.text
212
    assert '<img alt="" src="tempfile?' in resp.text
213
    tempfile_id = resp.text[resp.text.index('tempfile?') :].split('&', 1)[0].split('=')[1]
214

  
215
    resp_tempfile = app.get('/test/tempfile?t=%s' % tempfile_id)
216
    assert resp_tempfile.body == image_content
217

  
218
    if Image:
219
        # check thumbnailing of image in validation page
220
        resp_thumbnail = app.get('/test/tempfile?t=%s&thumbnail=1' % tempfile_id)
221
        assert resp_thumbnail.content_type == 'image/png'
222

  
223
    resp = resp.form.submit('submit').follow()
224
    assert '<img ' in resp.text
225
    assert 'download?f=0&thumbnail=1' in resp.text
226
    resp = resp.goto('download?f=0&thumbnail=1')
227
    assert '/thumbnail/' in resp.location
228
    resp = resp.follow()
229
    if Image:
230
        # check thumbnailing of image in submitted form
231
        assert resp.content_type == 'image/png'
232

  
233
        # check a fake image is not sent back
234
        upload = Upload('test.jpg', b'<script>evil javascript</script>', 'image/jpeg')
235
        app = get_app(pub)
236
        resp = app.get('/test/')
237
        resp.forms[0]['f0$file'] = upload
238
        resp = resp.forms[0].submit('submit')
239
        assert '<img alt="" src="tempfile?' not in resp.text
240

  
241

  
242
def test_form_file_field_submit_document_type(pub):
243
    FormDef.wipe()
244
    formdef = FormDef()
245
    formdef.name = 'test'
246
    formdef.fields = [
247
        fields.FileField(
248
            id='0',
249
            label='file',
250
            document_type={
251
                'id': 1,
252
                'mimetypes': ['image/*'],
253
                'label': 'Image files',
254
            },
255
        )
256
    ]
257
    formdef.store()
258
    formdef.data_class().wipe()
259

  
260
    upload = Upload('test.txt', b'foobar', 'application/force-download')
261

  
262
    resp = get_app(pub).get('/test/')
263
    resp.form['f0$file'] = upload
264
    resp = resp.form.submit('submit')
265
    assert 'invalid file type' in resp.text
266

  
267
    with open(os.path.join(os.path.dirname(__file__), '..', 'image-with-gps-data.jpeg'), 'rb') as fd:
268
        image_content = fd.read()
269
    upload = Upload('test.jpg', image_content, 'image/jpeg')
270
    resp = get_app(pub).get('/test/')
271
    resp.form['f0$file'] = upload
272
    resp = resp.form.submit('submit')
273
    assert 'Check values then click submit.' in resp.text
274

  
275

  
276
def test_form_file_field_submit_max_file_size(pub):
277
    FormDef.wipe()
278
    formdef = FormDef()
279
    formdef.name = 'test'
280
    formdef.fields = [fields.FileField(id='0', label='file', max_file_size='1ko')]
281
    formdef.store()
282
    formdef.data_class().wipe()
283

  
284
    upload = Upload('test.txt', b'foobar' * 1000, 'application/force-download')
285
    resp = get_app(pub).get('/test/')
286
    resp.form['f0$file'] = upload
287
    resp = resp.form.submit('submit')
288
    assert 'over file size limit (1ko)' in resp.text
289

  
290
    upload = Upload('test.txt', b'foobar' * 100, 'application/force-download')
291
    resp = get_app(pub).get('/test/')
292
    resp.form['f0$file'] = upload
293
    resp = resp.form.submit('submit')
294
    assert 'Check values then click submit.' in resp.text
295

  
296

  
297
def test_form_file_field_submit_wrong_mimetype(pub):
298
    FormDef.wipe()
299
    formdef = FormDef()
300
    formdef.name = 'test'
301
    formdef.fields = [fields.FileField(id='0', label='file')]
302
    formdef.store()
303
    formdef.data_class().wipe()
304

  
305
    upload = Upload('test.txt', b'foobar', 'application/force-download')
306

  
307
    resp = get_app(pub).get('/test/')
308
    resp.forms[0]['f0$file'] = upload
309
    resp = resp.forms[0].submit('submit')
310
    assert 'Check values then click submit.' in resp.text
311
    resp = resp.forms[0].submit('submit')
312
    assert resp.status_int == 302
313
    resp = resp.follow()
314
    assert 'The form has been recorded' in resp.text
315
    resp = resp.click('test.txt')
316
    assert resp.location.endswith('/test.txt')
317
    resp = resp.follow()
318
    assert resp.content_type == 'text/plain'
319
    assert resp.text == 'foobar'
320

  
321
    upload = Upload('test.pdf', b'%PDF-1.4 ...', 'application/force-download')
322

  
323
    resp = get_app(pub).get('/test/')
324
    resp.forms[0]['f0$file'] = upload
325
    resp = resp.forms[0].submit('submit')
326
    assert 'Check values then click submit.' in resp.text
327
    resp = resp.forms[0].submit('submit')
328
    assert resp.status_int == 302
329
    resp = resp.follow()
330
    assert 'The form has been recorded' in resp.text
331
    resp = resp.click('test.pdf')
332
    assert resp.location.endswith('/test.pdf')
333
    resp = resp.follow()
334
    assert resp.content_type == 'application/pdf'
335
    assert resp.text == '%PDF-1.4 ...'
336

  
337

  
338
def test_form_file_field_submit_blacklist(pub):
339
    FormDef.wipe()
340
    formdef = FormDef()
341
    formdef.name = 'test'
342
    formdef.fields = [fields.FileField(id='0', label='file')]
343
    formdef.store()
344
    formdef.data_class().wipe()
345

  
346
    # application/x-ms-dos-executable
347
    upload = Upload('test.exe', b'MZ...', 'application/force-download')
348
    resp = get_app(pub).get('/test/')
349
    resp.forms[0]['f0$file'] = upload
350
    resp = resp.forms[0].submit('submit')
351
    assert 'forbidden file type' in resp.text
352

  
353
    # define custom blacklist
354
    pub.load_site_options()
355
    if not pub.site_options.has_section('options'):
356
        pub.site_options.add_section('options')
357
    pub.site_options.set('options', 'blacklisted-file-types', 'application/pdf')
358
    with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
359
        pub.site_options.write(fd)
360

  
361
    # check against mime type
362
    upload = Upload('test.pdf', b'%PDF-1.4 ...', 'application/force-download')
363
    resp = get_app(pub).get('/test/')
364
    resp.forms[0]['f0$file'] = upload
365
    resp = resp.forms[0].submit('submit')
366
    assert 'forbidden file type' in resp.text
367

  
368
    # check against extension
369
    pub.site_options.set('options', 'blacklisted-file-types', '.pdf')
370
    with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
371
        pub.site_options.write(fd)
372

  
373
    upload = Upload('test.pdf', b'%PDF-1.4 ...', 'application/force-download')
374
    resp = get_app(pub).get('/test/')
375
    resp.forms[0]['f0$file'] = upload
376
    resp = resp.forms[0].submit('submit')
377
    assert 'forbidden file type' in resp.text
0
-