Projet

Général

Profil

0001-cartads_cs-check-CERFA-uploads-are-PDF-with-embedded.patch

Frédéric Péters, 03 septembre 2019 18:48

Télécharger (8,53 ko)

Voir les différences:

Subject: [PATCH] cartads_cs: check CERFA uploads are PDF with embedded forms
 (#35794)

 passerelle/apps/cartads_cs/models.py |  10 +++
 setup.py                             |   1 +
 tests/data/pdf-form.pdf              | 112 +++++++++++++++++++++++++++
 tests/test_cartads_cs.py             |  19 ++++-
 4 files changed, 138 insertions(+), 4 deletions(-)
 create mode 100644 tests/data/pdf-form.pdf
passerelle/apps/cartads_cs/models.py
23 23
from xml.etree import ElementTree as etree
24 24
import zipfile
25 25

  
26
import pdfrw
27
import pdfrw.findobjs
28

  
26 29
from Crypto.Cipher import AES
27 30

  
28 31
from django.conf import settings
......
434 437
            return []
435 438
        signer = Signer(salt='cart@ds_cs')
436 439
        tracking_code = signer.unsign(token)
440
        if id_piece.startswith('cerfa-'):
441
            try:
442
                pdf = pdfrw.PdfReader(request.FILES['files[]'])
443
                if not any(pdfrw.findobjs.find_objects(pdf, valid_subtypes=(pdfrw.PdfName.Form,))):
444
                    return [{'error': _('The CERFA should not be a scanned document.')}]
445
            except pdfrw.PdfParseError:
446
                return [{'error': _('The CERFA should be a PDF file.')}]
437 447
        file_upload = CartaDSFile(
438 448
                tracking_code=tracking_code,
439 449
                id_piece=id_piece,
setup.py
108 108
            'pycrypto',
109 109
            'unidecode',
110 110
            'paramiko',
111
            'pdfrw',
111 112
        ],
112 113
        cmdclass={
113 114
            'build': build,
tests/data/pdf-form.pdf
1
%PDF-1.4
2
%???? ReportLab Generated PDF document http://www.reportlab.com
3
1 0 obj
4
<<
5
/F1 2 0 R
6
>>
7
endobj
8
2 0 obj
9
<<
10
/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font
11
>>
12
endobj
13
3 0 obj
14
<</Type /Encoding /Differences [24 /breve /caron /circumflex /dotaccent /hungarumlaut /ogonek /ring /tilde 39 /quotesingle 96 /grave 128 /bullet /dagger /daggerdbl /ellipsis /emdash /endash /florin /fraction /guilsinglleft /guilsinglright /minus /perthousand /quotedblbase /quotedblleft /quotedblright /quoteleft /quoteright /quotesinglbase /trademark /fi /fl /Lslash /OE /Scaron /Ydieresis /Zcaron /dotlessi /lslash /oe /scaron /zcaron 160 /Euro 164 /currency 166 /brokenbar 168 /dieresis /copyright /ordfeminine 172 /logicalnot /.notdef /registered /macron /degree /plusminus /twosuperior /threesuperior /acute /mu 183 /periodcentered /cedilla /onesuperior /ordmasculine 188 /onequarter /onehalf /threequarters 192 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis]>>
15
endobj
16
4 0 obj
17
<< /BaseFont /Helvetica /Subtype /Type1 /Name /Helv /Type /Font /Encoding 3 0 R >>
18
endobj
19
5 0 obj
20
<<
21
/BBox [ 0 0 300 36 ] /Filter [ /FlateDecode ] /FormType 1 /Length 171 /Matrix [ 1 0 0 1 0 0 ] /Resources << /ProcSet [/PDF /Text] /Font <</Helv 4 0 R>> >> 
22
  /Subtype /Form /Type /XObject
23
>>
24
stream
25
x?MOK
26
?0??)f??6??6ۖR7](/`???ߗ~??7?f?LR0)2K??EE?dr?nH???YޡE0Z?????Y$?e?wp?Gۢ&?e?'?u?m?)bԜϹ?*q???ȧ?HÏe[?)??????Oi[4(?c??
?&WJf4?v?n??@pB?V??5endstream
27
endobj
28
6 0 obj
29
<<
30
/AP <<
31
/N 5 0 R
32
>> /BS <<
33
/S /I /W 1
34
>> /DA (/Helv 12 Tf .1 .1 .1 rg) /DV () /F 4 /FT /Tx 
35
  /Ff 0 /MK <<
36
/BC [ .1 .1 .1 ] /BG [ .8 .843 1 ]
37
>> /MaxLen 100 /P 7 0 R /Rect [ 110 635 410 671 ] /Subtype /Widget 
38
  /T (fname) /TU (First Name) /Type /Annot /V ()
39
>>
40
endobj
41
7 0 obj
42
<<
43
/Annots [ 6 0 R ] /Contents 11 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 10 0 R /Resources <<
44
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
45
>> /Rotate 0 
46
  /Trans <<
47

  
48
>> /Type /Page
49
>>
50
endobj
51
8 0 obj
52
<<
53
/AcroForm 12 0 R /PageMode /UseNone /Pages 10 0 R /Type /Catalog
54
>>
55
endobj
56
9 0 obj
57
<<
58
/Author (anonymous) /CreationDate (D:20190903184353+00'00') /Creator (ReportLab PDF Library - www.reportlab.com) /Keywords () /ModDate (D:20190903184353+00'00') /Producer (ReportLab PDF Library - www.reportlab.com) 
59
  /Subject (unspecified) /Title (untitled) /Trapped /False
60
>>
61
endobj
62
10 0 obj
63
<<
64
/Count 1 /Kids [ 7 0 R ] /Type /Pages
65
>>
66
endobj
67
11 0 obj
68
<<
69
/Filter [ /ASCII85Decode /FlateDecode ] /Length 126
70
>>
71
stream
72
Gaqck0a`Ou'F"A`MQ&2A5'L)8'f:o0@;c^9<<BGqqH78BhIBr$6rTs)+"nHeodnUUT.#"2021%_VSBG#BeHRGDrs4>a&%@t[l74FM(YU@Fr1LA@q2TV2=(]H6Pek~>endstream
73
endobj
74
12 0 obj
75
<<
76
/DA (/Helv 0 Tf 0 g) /DR << /Encoding
77
<<
78
/RLAFencoding
79
3 0 R
80
>>
81
/Font << /Helv 4 0 R >>
82
>> /Fields [ 6 0 R ]
83
>>
84
endobj
85
xref
86
0 13
87
0000000000 65535 f 
88
0000000073 00000 n 
89
0000000104 00000 n 
90
0000000211 00000 n 
91
0000001533 00000 n 
92
0000001631 00000 n 
93
0000002028 00000 n 
94
0000002307 00000 n 
95
0000002530 00000 n 
96
0000002616 00000 n 
97
0000002912 00000 n 
98
0000002972 00000 n 
99
0000003189 00000 n 
100
trailer
101
<<
102
/ID 
103
[<30d7bc8d9857e1dc55dd88e74a04dac2><30d7bc8d9857e1dc55dd88e74a04dac2>]
104
% ReportLab generated PDF document -- digest (http://www.reportlab.com)
105

  
106
/Info 9 0 R
107
/Root 8 0 R
108
/Size 13
109
>>
110
startxref
111
3320
112
%%EOF
tests/test_cartads_cs.py
1 1
# -*- coding: utf-8 -*-
2 2

  
3 3
import datetime
4
import os
4 5

  
5 6
import mock
6 7
from httmock import HTTMock
......
142 143

  
143 144
    resp = app.post(data[0]['files'][0]['url'],
144 145
                    upload_files=[('files[]', 'test.pdf', '%PDF...')])
146
    assert resp.json == [{'error': 'The CERFA should be a PDF file.'}]
147

  
148
    pdf_contents = open(os.path.join(os.path.dirname(__file__), 'data', 'minimal.pdf')).read()
149
    resp = app.post(data[0]['files'][0]['url'],
150
                    upload_files=[('files[]', 'test.pdf', pdf_contents)])
151
    assert resp.json == [{'error': 'The CERFA should not be a scanned document.'}]
152

  
153
    pdf_contents = open(os.path.join(os.path.dirname(__file__), 'data', 'pdf-form.pdf')).read()
154
    resp = app.post(data[0]['files'][0]['url'],
155
                    upload_files=[('files[]', 'test.pdf', pdf_contents)])
145 156
    cerfa_token = resp.json[0]['token']
146 157

  
147 158
    resp = app.get('/cartads-cs/test/pieces?type_dossier_id=CU&objet_demande_id=1&tracking_code=BBBBBBBB')
......
156 167
    assert 'name' not in data[0]['files'][0]
157 168

  
158 169
    resp = app.post(data[0]['files'][0]['url'],
159
                    upload_files=[('files[]', 'test.pdf', '%PDF...')])
170
                    upload_files=[('files[]', 'test.pdf', pdf_contents)])
160 171

  
161 172
    resp = app.post(data[1]['files'][0]['url'],
162
                    upload_files=[('files[]', 'test.pdf', '%PDF...')])
173
                    upload_files=[('files[]', 'test.pdf', pdf_contents)])
163 174
    resp = app.post(data[1]['files'][0]['url'],
164
                    upload_files=[('files[]', 'test.pdf', '%PDF...')])
175
                    upload_files=[('files[]', 'test.pdf', pdf_contents)])
165 176
    resp = app.get('/cartads-cs/test/pieces?type_dossier_id=CU&objet_demande_id=1&tracking_code=BBBBBBBB')
166 177
    data = resp.json['data']
167 178
    assert len(data[1]['files']) == 3
......
170 181
    assert resp.json == {'result': False, 'err': 0}
171 182

  
172 183
    resp = app.post(data[2]['files'][0]['url'],
173
                    upload_files=[('files[]', 'test.pdf', '%PDF...')])
184
                    upload_files=[('files[]', 'test.pdf', pdf_contents)])
174 185

  
175 186
    resp = app.get('/cartads-cs/test/check_pieces?type_dossier_id=CU&objet_demande_id=1&tracking_code=BBBBBBBB')
176 187
    assert resp.json == {'result': True, 'err': 0}
177
-