diff --git a/passerelle_reunion_fsn/migrations/0003_csv_checksum.py b/passerelle_reunion_fsn/migrations/0003_csv_checksum.py new file mode 100644 index 0000000..b29b030 --- /dev/null +++ b/passerelle_reunion_fsn/migrations/0003_csv_checksum.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.29 on 2020-04-19 05:45 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('passerelle_reunion_fsn', '0002_entreprise_missing_column'), + ] + + operations = [ + migrations.AddField( + model_name='dsdossier', + name='csv_checksum', + field=models.CharField(default='', max_length=256), + preserve_default=False, + ), + ] diff --git a/passerelle_reunion_fsn/models.py b/passerelle_reunion_fsn/models.py index 1ad52db..4ff327b 100644 --- a/passerelle_reunion_fsn/models.py +++ b/passerelle_reunion_fsn/models.py @@ -16,7 +16,9 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +import base64 import csv +import hashlib from io import BytesIO from django.core.urlresolvers import reverse @@ -283,16 +285,19 @@ query getDossiers($demarcheNumber: Int!, $createdSince: ISO8601DateTime, $first: for champ in dossier['champs']: if 'file' in champ: file_url = champ['file']['url'] - # TODO : check file integrity - # file_checksum = champ['file']['checksum'] filename = champ['file']['filename'] response = self.requests.get(file_url) assert response.status_code == 200 ds_dossier = DSDossier.objects.create( resource=self, ds_id=id_dossier, csv_filename=filename, - ds_state=dossier['state'] + ds_state=dossier['state'], csv_checksum=champ['file']['checksum'] ) ds_dossier.csv_file.save(filename, BytesIO(response.content)) + + filhash = hashlib.md5(ds_dossier.csv_file.read()) + if base64.b64encode(filhash.digest()).decode() != ds_dossier.csv_checksum: + raise APIError('Bad checksum') + res.append(ds_dossier.to_json(request)) break @@ -452,6 +457,7 @@ class DSDossier(models.Model): ds_state = models.CharField(max_length=256) csv_file = models.FileField(upload_to=csv_file_location) csv_filename = models.CharField(max_length=256) + csv_checksum = models.CharField(max_length=256) last_update_datetime = models.DateTimeField(auto_now=True) def to_json(self, request): @@ -472,6 +478,7 @@ class DSDossier(models.Model): 'ds_state': self.ds_state, 'csv_filename': self.csv_filename, 'csv_file': csv_file_url, + 'csv_checksum': self.csv_checksum, 'last_update_datetime': self.last_update_datetime }