From 817dc9a8f3ea07aa7a81adc3b10e0686182451ec Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 17 Feb 2021 17:38:10 +0100 Subject: [PATCH 1/8] up the version --- ereuse_devicehub/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ereuse_devicehub/__init__.py b/ereuse_devicehub/__init__.py index a20c909b..53f0b176 100644 --- a/ereuse_devicehub/__init__.py +++ b/ereuse_devicehub/__init__.py @@ -1 +1 @@ -__version__ = "1.0.4-beta" +__version__ = "1.0.5-beta" From b9bd367487385dca95976e4ac65c15a701342a0f Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 17 Feb 2021 17:38:54 +0100 Subject: [PATCH 2/8] verify one document --- .../resources/documents/documents.py | 26 +++++++++++++++---- .../documents/templates/documents/stamp.html | 24 +++++++++++++++++ ereuse_devicehub/resources/hash_reports.py | 5 ++++ 3 files changed, 50 insertions(+), 5 deletions(-) diff --git a/ereuse_devicehub/resources/documents/documents.py b/ereuse_devicehub/resources/documents/documents.py index 33eca9b8..11e84602 100644 --- a/ereuse_devicehub/resources/documents/documents.py +++ b/ereuse_devicehub/resources/documents/documents.py @@ -24,7 +24,7 @@ from ereuse_devicehub.resources.device.views import DeviceView from ereuse_devicehub.resources.documents.device_row import DeviceRow, StockRow, ActionRow from ereuse_devicehub.resources.lot import LotView from ereuse_devicehub.resources.lot.models import Lot -from ereuse_devicehub.resources.hash_reports import insert_hash, ReportHash +from ereuse_devicehub.resources.hash_reports import insert_hash, ReportHash, verify_hash class Format(enum.Enum): @@ -244,12 +244,28 @@ class StampsView(View): This view render one public ans static page for see the links for to do the check of one csv file """ - def get(self): + def get_url_path(self): url = urlutils.URL(request.url) url.normalize() url.path_parts = url.path_parts[:-2] + ['check', ''] - url_path = url.to_text() - return flask.render_template('documents/stamp.html', rq_url=url_path) + return url.to_text() + + def get(self): + result = ('', '') + return flask.render_template('documents/stamp.html', rq_url=self.get_url_path(), + result=result) + + def post(self): + result = ('', '') + if 'docUpload' in request.files: + file_check = request.files['docUpload'] + result = ('Bad', 'Sorry, this file has not been produced by this website') + if file_check.mimetype in ['text/csv', 'application/pdf']: + if verify_hash(file_check): + result = ('Ok', 'Yes, this file has been produced by this website') + + return flask.render_template('documents/stamp.html', rq_url=self.get_url_path(), + result=result) class DocumentDef(Resource): @@ -305,7 +321,7 @@ class DocumentDef(Resource): self.add_url_rule('/check/', defaults={}, view_func=check_view, methods=get) stamps_view = StampsView.as_view('StampsView', definition=self, auth=app.auth) - self.add_url_rule('/stamps/', defaults={}, view_func=stamps_view, methods=get) + self.add_url_rule('/stamps/', defaults={}, view_func=stamps_view, methods={'GET', 'POST'}) actions_view = ActionsDocumentView.as_view('ActionsDocumentView', definition=self, diff --git a/ereuse_devicehub/resources/documents/templates/documents/stamp.html b/ereuse_devicehub/resources/documents/templates/documents/stamp.html index c204c2ff..0a7bfaf3 100644 --- a/ereuse_devicehub/resources/documents/templates/documents/stamp.html +++ b/ereuse_devicehub/resources/documents/templates/documents/stamp.html @@ -38,6 +38,17 @@
+ +
+ +
+
+ +
+ +
+
+
diff --git a/ereuse_devicehub/resources/hash_reports.py b/ereuse_devicehub/resources/hash_reports.py index f84e4b18..f44a79be 100644 --- a/ereuse_devicehub/resources/hash_reports.py +++ b/ereuse_devicehub/resources/hash_reports.py @@ -32,3 +32,8 @@ def insert_hash(bfile): db.session.add(db_hash) db.session.commit() db.session.flush() + + +def verify_hash(bfile): + hash3 = hashlib.sha3_256(bfile.read()).hexdigest() + return ReportHash.query.filter(ReportHash.hash3 == hash3).count() From 32c4844aed3e2deecbd50294dcfd34d68eddb967 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 17 Feb 2021 23:14:40 +0100 Subject: [PATCH 3/8] adding test for verify stamp --- tests/test_basic.py | 1 - tests/test_documents.py | 40 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/tests/test_basic.py b/tests/test_basic.py index b5e52805..77103f1b 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -27,7 +27,6 @@ def test_dependencies(): def test_api_docs(client: Client): """Tests /apidocs correct initialization.""" docs, _ = client.get('/apidocs') - # import pdb; pdb.set_trace() assert set(docs['paths'].keys()) == { '/actions/', '/apidocs', diff --git a/tests/test_documents.py b/tests/test_documents.py index fc4f8ea2..173be232 100644 --- a/tests/test_documents.py +++ b/tests/test_documents.py @@ -1,8 +1,9 @@ import csv import hashlib from datetime import datetime -from io import StringIO +from io import StringIO, BytesIO from pathlib import Path +from flask import url_for import pytest from werkzeug.exceptions import Unauthorized @@ -459,3 +460,40 @@ def test_get_document_lots(user: UserClient, user2: UserClient): assert export_csv[1][3] == 'comments,lot1,testcomment-lot1,' or 'comments,lot2,testcomment-lot2,' assert export2_csv[1][1] == 'Lot3-User2' assert export2_csv[1][3] == 'comments,lot3,testcomment-lot3,' + + +@pytest.mark.mvp +def test_verify_stamp(user: UserClient, client: Client): + """Test verify stamp of one export device information in a csv file.""" + snapshot, _ = user.post(file('basic.snapshot'), res=Snapshot) + csv_str, _ = user.get(res=documents.DocumentDef.t, + item='devices/', + accept='text/csv', + query=[('filter', {'type': ['Computer']})]) + + response, _ = client.post(res=documents.DocumentDef.t, + item='stamps/', + content_type='multipart/form-data', + accept='text/html', + data={'docUpload': [(BytesIO(bytes(csv_str, 'utf-8')), 'example.csv')]}, + status=200) + assert "alert alert-info" in response + assert not "alert alert-danger" in response + + response, _ = client.post(res=documents.DocumentDef.t, + item='stamps/', + content_type='multipart/form-data', + accept='text/html', + data={'docUpload': [(BytesIO(b'abc'), 'example.csv')]}, + status=200) + + assert not "alert alert-info" in response + assert "alert alert-danger" in response + + response, _ = client.get(res=documents.DocumentDef.t, + item='stamps/', + accept='text/html', + status=200) + + assert not "alert alert-info" in response + assert not "alert alert-danger" in response From 24669631cef11c7c4f14831fbfdb82942af1e638 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 18 Feb 2021 11:36:55 +0100 Subject: [PATCH 4/8] adding hash for all documents than you download --- ereuse_devicehub/resources/documents/documents.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/ereuse_devicehub/resources/documents/documents.py b/ereuse_devicehub/resources/documents/documents.py index 11e84602..4e8a073b 100644 --- a/ereuse_devicehub/resources/documents/documents.py +++ b/ereuse_devicehub/resources/documents/documents.py @@ -77,6 +77,7 @@ class DocumentView(DeviceView): res = flask_weasyprint.render_pdf( flask_weasyprint.HTML(string=template), download_filename='{}.pdf'.format(type) ) + insert_hash(res.data) else: res = flask.make_response(template) return res @@ -183,7 +184,9 @@ class LotsDocumentView(LotView): cw.writerow(l.keys()) first = False cw.writerow(l.values()) - output = make_response(data.getvalue()) + bfile = data.getvalue().encode('utf-8') + output = make_response(bfile) + insert_hash(bfile) output.headers['Content-Disposition'] = 'attachment; filename=lots-info.csv' output.headers['Content-type'] = 'text/csv' return output @@ -220,7 +223,9 @@ class StockDocumentView(DeviceView): cw.writerow(d.keys()) first = False cw.writerow(d.values()) - output = make_response(data.getvalue()) + bfile = data.getvalue().encode('utf-8') + output = make_response(bfile) + insert_hash(bfile) output.headers['Content-Disposition'] = 'attachment; filename=devices-stock.csv' output.headers['Content-type'] = 'text/csv' return output From 1cf3c61db53ffa31aac86949d9c54fe92a8797cf Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 18 Feb 2021 11:37:37 +0100 Subject: [PATCH 5/8] adding test for verify all documents --- tests/test_documents.py | 133 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 125 insertions(+), 8 deletions(-) diff --git a/tests/test_documents.py b/tests/test_documents.py index 173be232..c23ab6ba 100644 --- a/tests/test_documents.py +++ b/tests/test_documents.py @@ -481,19 +481,136 @@ def test_verify_stamp(user: UserClient, client: Client): assert not "alert alert-danger" in response response, _ = client.post(res=documents.DocumentDef.t, - item='stamps/', - content_type='multipart/form-data', - accept='text/html', - data={'docUpload': [(BytesIO(b'abc'), 'example.csv')]}, - status=200) + item='stamps/', + content_type='multipart/form-data', + accept='text/html', + data={'docUpload': [(BytesIO(b'abc'), 'example.csv')]}, + status=200) assert not "alert alert-info" in response assert "alert alert-danger" in response response, _ = client.get(res=documents.DocumentDef.t, - item='stamps/', - accept='text/html', - status=200) + item='stamps/', + accept='text/html', + status=200) assert not "alert alert-info" in response assert not "alert alert-danger" in response + + +@pytest.mark.mvp +def test_verify_stamp_log_info(user: UserClient, client: Client): + """Test verify stamp of one export lots-info in a csv file.""" + + l, _ = user.post({'name': 'Lot1', 'description': 'comments,lot1,testcomment-lot1,'}, res=Lot) + l, _ = user.post({'name': 'Lot2', 'description': 'comments,lot2,testcomment-lot2,'}, res=Lot) + + csv_str, _ = user.get(res=documents.DocumentDef.t, + item='lots/', + accept='text/csv') + + response, _ = client.post(res=documents.DocumentDef.t, + item='stamps/', + content_type='multipart/form-data', + accept='text/html', + data={'docUpload': [(BytesIO(bytes(csv_str, 'utf-8')), + 'example.csv')]}, + status=200) + assert "alert alert-info" in response + + +@pytest.mark.mvp +def test_verify_stamp_devices_stock(user: UserClient, client: Client): + """Test verify stamp of one export device information in a csv file.""" + + snapshot, _ = user.post(file('basic.snapshot'), res=Snapshot) + + csv_str, _ = user.get(res=documents.DocumentDef.t, + item='stock/', + accept='text/csv', + query=[('filter', {'type': ['Computer']})]) + + response, _ = client.post(res=documents.DocumentDef.t, + item='stamps/', + content_type='multipart/form-data', + accept='text/html', + data={'docUpload': [(BytesIO(bytes(csv_str, 'utf-8')), + 'example.csv')]}, + status=200) + assert "alert alert-info" in response + + +@pytest.mark.mvp +def test_verify_stamp_csv_actions(user: UserClient, client: Client): + """Test verify stamp of one export device information in a csv file with others users.""" + acer = file('acer.happy.battery.snapshot') + snapshot, _ = user.post(acer, res=Snapshot) + device_id = snapshot['device']['id'] + post_request = {"transaction": "ccc", "name": "John", "endUsers": 1, + "devices": [device_id], "description": "aaa", + "finalUserCode": "abcdefjhi", + "startTime": "2020-11-01T02:00:00+00:00", + "endTime": "2020-12-01T02:00:00+00:00" + } + + user.post(res=Allocate, data=post_request) + hdd = [c for c in acer['components'] if c['type'] == 'HardDrive'][0] + hdd_action = [a for a in hdd['actions'] if a['type'] == 'TestDataStorage'][0] + hdd_action['lifetime'] += 1000 + acer.pop('elapsed') + acer['licence_version'] = '1.0.0' + snapshot, _ = client.post(acer, res=Live) + + csv_str, _ = user.get(res=documents.DocumentDef.t, + item='actions/', + accept='text/csv', + query=[('filter', {'type': ['Computer']})]) + + response, _ = client.post(res=documents.DocumentDef.t, + item='stamps/', + content_type='multipart/form-data', + accept='text/html', + data={'docUpload': [(BytesIO(bytes(csv_str, 'utf-8')), + 'example.csv')]}, + status=200) + assert "alert alert-info" in response + + +@pytest.mark.mvp +def test_verify_stamp_erasure_certificate(user: UserClient, client: Client): + """Test verify stamp of one export certificate in PDF.""" + s = file('erase-sectors.snapshot') + snapshot, response = user.post(s, res=Snapshot) + # import pdb; pdb.set_trace() + + doc, _ = user.get(res=documents.DocumentDef.t, + item='erasures/', + query=[('filter', {'id': [snapshot['device']['id']]})], + accept=ANY) + + response, _ = client.post(res=documents.DocumentDef.t, + item='stamps/', + content_type='multipart/form-data', + accept='text/html', + data={'docUpload': [(BytesIO(bytes(doc, 'utf-8')), + 'example.csv')]}, + status=200) + assert "alert alert-danger" in response + + doc, _ = user.get(res=documents.DocumentDef.t, + item='erasures/', + query=[ + ('filter', {'id': [snapshot['device']['id']]}), + ('format', 'PDF') + ], + accept='application/pdf') + + response, _ = client.post(res=documents.DocumentDef.t, + item='stamps/', + content_type='multipart/form-data', + accept='text/html', + data={'docUpload': [(BytesIO(doc), + 'example.csv')]}, + status=200) + assert "alert alert-info" in response From 372427375dfeb85d1da8d516b721c797750a8269 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 4 Mar 2021 10:38:04 +0100 Subject: [PATCH 6/8] correct response for every stamp check --- ereuse_devicehub/resources/documents/documents.py | 8 ++++++-- .../resources/documents/templates/documents/stamp.html | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/ereuse_devicehub/resources/documents/documents.py b/ereuse_devicehub/resources/documents/documents.py index 4e8a073b..9d74ca10 100644 --- a/ereuse_devicehub/resources/documents/documents.py +++ b/ereuse_devicehub/resources/documents/documents.py @@ -264,10 +264,14 @@ class StampsView(View): result = ('', '') if 'docUpload' in request.files: file_check = request.files['docUpload'] - result = ('Bad', 'Sorry, this file has not been produced by this website') + bad = 'There are no coincidences. The attached file data does not come \ + from our backend or it has been subsequently modified.' + ok = '100% coincidence. The attached file contains data 100% existing in \ + to our backend' + result = ('Bad', bad) if file_check.mimetype in ['text/csv', 'application/pdf']: if verify_hash(file_check): - result = ('Ok', 'Yes, this file has been produced by this website') + result = ('Ok', ok) return flask.render_template('documents/stamp.html', rq_url=self.get_url_path(), result=result) diff --git a/ereuse_devicehub/resources/documents/templates/documents/stamp.html b/ereuse_devicehub/resources/documents/templates/documents/stamp.html index 0a7bfaf3..0a368f4d 100644 --- a/ereuse_devicehub/resources/documents/templates/documents/stamp.html +++ b/ereuse_devicehub/resources/documents/templates/documents/stamp.html @@ -40,11 +40,11 @@