From 9c3de1c25883362e551c88f9a2cb24808caf49b2 Mon Sep 17 00:00:00 2001 From: Xavier Bustamante Talavera Date: Sat, 17 Nov 2018 18:24:34 +0100 Subject: [PATCH] Complete ErasePhysical and EraseBasic.standards; remove EraseBasic.zeros --- ereuse_devicehub/dummy/dummy.py | 4 +++ .../files/dell-optiplexgx520.snapshot.11.yaml | 2 +- .../dummy/files/hp1.snapshot.11.yaml | 2 +- .../dummy/files/hp2.snapshot.11.yaml | 4 +-- .../files/lenovo-3493BAG.snapshot.11.yaml | 3 +-- .../dummy/files/nec.snapshot.11.yaml | 1 - .../files/real-eee-1001pxd.snapshot.11.yaml | 2 +- ereuse_devicehub/resources/enums.py | 16 ++++++++--- ereuse_devicehub/resources/event/__init__.py | 5 ++++ ereuse_devicehub/resources/event/models.py | 6 ----- ereuse_devicehub/resources/event/models.pyi | 12 +++++++-- ereuse_devicehub/resources/event/schemas.py | 15 +++++++---- tests/files/erase-sectors-2-hdd.snapshot.yaml | 3 +-- tests/files/erase-sectors.snapshot.yaml | 3 +-- tests/files/workbench-server-3.erase.yaml | 1 - tests/test_basic.py | 2 +- tests/test_event.py | 27 +++++++++++-------- tests/test_snapshot.py | 14 ++++++---- tests/test_workbench.py | 1 - 19 files changed, 76 insertions(+), 47 deletions(-) diff --git a/ereuse_devicehub/dummy/dummy.py b/ereuse_devicehub/dummy/dummy.py index 04fe7b97..62d6f0a3 100644 --- a/ereuse_devicehub/dummy/dummy.py +++ b/ereuse_devicehub/dummy/dummy.py @@ -80,6 +80,10 @@ class Dummy: sample_pc = s['device']['id'] else: pcs.add(s['device']['id']) + if s.get('uuid', None) == 'de4f495e-c58b-40e1-a33e-46ab5e84767e': # oreo + # Make one hdd ErasePhysical + hdd = next(hdd for hdd in s['components'] if hdd['type'] == 'HardDrive') + user.post({'type': 'ErasePhysical', 'method': 'Shred', 'device': hdd['id']}, res=m.Event) assert sample_pc print('PC sample is', sample_pc) # Link tags and eTags diff --git a/ereuse_devicehub/dummy/files/dell-optiplexgx520.snapshot.11.yaml b/ereuse_devicehub/dummy/files/dell-optiplexgx520.snapshot.11.yaml index 74bbfb97..8677c1d8 100644 --- a/ereuse_devicehub/dummy/files/dell-optiplexgx520.snapshot.11.yaml +++ b/ereuse_devicehub/dummy/files/dell-optiplexgx520.snapshot.11.yaml @@ -97,7 +97,7 @@ "endTime": "2018-07-11T11:42:12.971177" } ], - "zeros": false, + "severity": "Info", "type": "EraseBasic", "endTime": "2018-07-11T11:42:12.975358", diff --git a/ereuse_devicehub/dummy/files/hp1.snapshot.11.yaml b/ereuse_devicehub/dummy/files/hp1.snapshot.11.yaml index 87a7f348..70b6fc5c 100644 --- a/ereuse_devicehub/dummy/files/hp1.snapshot.11.yaml +++ b/ereuse_devicehub/dummy/files/hp1.snapshot.11.yaml @@ -72,7 +72,7 @@ "events": [ { "type": "EraseBasic", - "zeros": false, + "endTime": "2018-07-11T11:56:52.390306", "severity": "Info", "startTime": "2018-07-11T10:49:31.998217", diff --git a/ereuse_devicehub/dummy/files/hp2.snapshot.11.yaml b/ereuse_devicehub/dummy/files/hp2.snapshot.11.yaml index aa456507..0db4e9d4 100644 --- a/ereuse_devicehub/dummy/files/hp2.snapshot.11.yaml +++ b/ereuse_devicehub/dummy/files/hp2.snapshot.11.yaml @@ -81,7 +81,7 @@ }, { "startTime": "2018-07-11T10:32:14.445306", - "zeros": false, + "type": "EraseBasic", "severity": "Info", "endTime": "2018-07-11T10:53:46.442123", @@ -113,7 +113,7 @@ }, { "startTime": "2018-07-11T10:53:46.442187", - "zeros": false, + "type": "EraseBasic", "severity": "Info", "endTime": "2018-07-11T11:16:28.469899", diff --git a/ereuse_devicehub/dummy/files/lenovo-3493BAG.snapshot.11.yaml b/ereuse_devicehub/dummy/files/lenovo-3493BAG.snapshot.11.yaml index cd3e4ae4..1a5e60ce 100644 --- a/ereuse_devicehub/dummy/files/lenovo-3493BAG.snapshot.11.yaml +++ b/ereuse_devicehub/dummy/files/lenovo-3493BAG.snapshot.11.yaml @@ -110,8 +110,7 @@ "endTime": "2018-07-11T14:04:04.861590", "severity": "Info" } - ], - "zeros": false + ] } ], "size": 238475, diff --git a/ereuse_devicehub/dummy/files/nec.snapshot.11.yaml b/ereuse_devicehub/dummy/files/nec.snapshot.11.yaml index c7cabd57..5be76871 100644 --- a/ereuse_devicehub/dummy/files/nec.snapshot.11.yaml +++ b/ereuse_devicehub/dummy/files/nec.snapshot.11.yaml @@ -104,7 +104,6 @@ "severity": "Info", "endTime": "2018-07-11T11:33:41.531918", "startTime": "2018-07-11T10:30:35.643855", - "zeros": false, "type": "EraseBasic", "steps": [ { diff --git a/ereuse_devicehub/dummy/files/real-eee-1001pxd.snapshot.11.yaml b/ereuse_devicehub/dummy/files/real-eee-1001pxd.snapshot.11.yaml index 75002dae..d7f0a946 100644 --- a/ereuse_devicehub/dummy/files/real-eee-1001pxd.snapshot.11.yaml +++ b/ereuse_devicehub/dummy/files/real-eee-1001pxd.snapshot.11.yaml @@ -105,7 +105,7 @@ ], "startTime": "2018-07-03T09:15:22.256074", "severity": "Info", - "zeros": false, + "endTime": "2018-07-03T10:32:11.848455" } ] diff --git a/ereuse_devicehub/resources/enums.py b/ereuse_devicehub/resources/enums.py index e761dcb9..6d2f344a 100644 --- a/ereuse_devicehub/resources/enums.py +++ b/ereuse_devicehub/resources/enums.py @@ -1,6 +1,7 @@ +from contextlib import suppress from distutils.version import StrictVersion from enum import Enum, IntEnum, unique -from typing import Union +from typing import Set, Union import inflection @@ -350,5 +351,14 @@ class ErasureStandards(Enum): return self.value @classmethod - def from_data_storage(cls, erasure): - raise NotImplementedError() + def from_data_storage(cls, erasure) -> Set['ErasureStandards']: + """Returns a set of erasure standards.""" + from ereuse_devicehub.resources.event import models as events + standards = set() + if isinstance(erasure, events.EraseSectors): + with suppress(ValueError): + first_step, *other_steps = erasure.steps + if isinstance(first_step, events.StepZero) \ + and all(isinstance(step, events.StepRandom) for step in other_steps): + standards.add(cls.HMG_IS5) + return standards diff --git a/ereuse_devicehub/resources/event/__init__.py b/ereuse_devicehub/resources/event/__init__.py index 23c0f21f..2acc7fd9 100644 --- a/ereuse_devicehub/resources/event/__init__.py +++ b/ereuse_devicehub/resources/event/__init__.py @@ -34,6 +34,11 @@ class EraseSectorsDef(EraseBasicDef): SCHEMA = schemas.EraseSectors +class ErasePhysicalDef(EraseBasicDef): + VIEW = None + SCHEMA = schemas.ErasePhysical + + class StepDef(Resource): VIEW = None SCHEMA = schemas.Step diff --git a/ereuse_devicehub/resources/event/models.py b/ereuse_devicehub/resources/event/models.py index c64871c7..5027bc25 100644 --- a/ereuse_devicehub/resources/event/models.py +++ b/ereuse_devicehub/resources/event/models.py @@ -311,11 +311,6 @@ class EraseBasic(JoinedWithOneDeviceMixin, EventWithOneDevice): Devicehub automatically shows the standards that each erasure follows. """ - zeros = Column(Boolean, nullable=False) - zeros.comment = """ - Whether this erasure had a first erasure step consisting of - only writing zeros. - """ @property def standards(self): @@ -330,7 +325,6 @@ class EraseSectors(EraseBasic): """A secured-way of erasing data storages, checking sector-by-sector the erasure, using `badblocks `_. """ - # todo make a property that says if the data wiping process is british... class ErasePhysical(EraseBasic): diff --git a/ereuse_devicehub/resources/event/models.pyi b/ereuse_devicehub/resources/event/models.pyi index 9ba0f86b..7628b8af 100644 --- a/ereuse_devicehub/resources/event/models.pyi +++ b/ereuse_devicehub/resources/event/models.pyi @@ -17,8 +17,8 @@ from teal.enums import Country from ereuse_devicehub.resources.agent.models import Agent from ereuse_devicehub.resources.device.models import Component, Computer, Device from ereuse_devicehub.resources.enums import AppearanceRange, Bios, ErasureStandards, \ - FunctionalityRange, PriceSoftware, RatingSoftware, ReceiverRole, Severity, \ - SnapshotExpectedEvents, SnapshotSoftware, TestDataStorageLength + FunctionalityRange, PhysicalErasureMethod, PriceSoftware, RatingSoftware, ReceiverRole, \ + Severity, SnapshotExpectedEvents, SnapshotSoftware, TestDataStorageLength from ereuse_devicehub.resources.models import Thing from ereuse_devicehub.resources.user.models import User @@ -364,6 +364,14 @@ class EraseSectors(EraseBasic): super().__init__(**kwargs) +class ErasePhysical(EraseBasic): + method = ... # type: Column + + def __init__(self, **kwargs) -> None: + super().__init__(**kwargs) + self.method = ... # type: PhysicalErasureMethod + + class Benchmark(EventWithOneDevice): pass diff --git a/ereuse_devicehub/resources/event/schemas.py b/ereuse_devicehub/resources/event/schemas.py index 074183ae..1b2ade28 100644 --- a/ereuse_devicehub/resources/event/schemas.py +++ b/ereuse_devicehub/resources/event/schemas.py @@ -1,5 +1,5 @@ from flask import current_app as app -from marshmallow import Schema as MarshmallowSchema, ValidationError, validates_schema +from marshmallow import Schema as MarshmallowSchema, ValidationError, fields as f, validates_schema from marshmallow.fields import Boolean, DateTime, Decimal, Float, Integer, List, Nested, String, \ TimeDelta, UUID from marshmallow.validate import Length, Range @@ -9,11 +9,12 @@ from teal.marshmallow import EnumField, IP, SanitizedStr, URL, Version from teal.resource import Schema from ereuse_devicehub.marshmallow import NestedOn +from ereuse_devicehub.resources import enums from ereuse_devicehub.resources.agent.schemas import Agent from ereuse_devicehub.resources.device.schemas import Component, Computer, Device from ereuse_devicehub.resources.enums import AppearanceRange, Bios, FunctionalityRange, \ - PriceSoftware, RATE_POSITIVE, RatingRange, RatingSoftware, ReceiverRole, Severity, \ - SnapshotExpectedEvents, SnapshotSoftware, TestDataStorageLength + PhysicalErasureMethod, PriceSoftware, RATE_POSITIVE, RatingRange, RatingSoftware, ReceiverRole, \ + Severity, SnapshotExpectedEvents, SnapshotSoftware, TestDataStorageLength from ereuse_devicehub.resources.event import models as m from ereuse_devicehub.resources.models import STR_BIG_SIZE, STR_SIZE from ereuse_devicehub.resources.schemas import Thing @@ -72,14 +73,18 @@ class Deallocate(EventWithMultipleDevices): class EraseBasic(EventWithOneDevice): - zeros = Boolean(required=True, description=m.EraseBasic.zeros.comment) - steps = NestedOn('Step', many=True, required=True) + steps = NestedOn('Step', many=True) + standards = f.List(EnumField(enums.ErasureStandards), dump_only=True) class EraseSectors(EraseBasic): pass +class ErasePhysical(EraseBasic): + method = EnumField(PhysicalErasureMethod, description=PhysicalErasureMethod.__doc__) + + class Step(Schema): type = String(description='Only required when it is nested.') start_time = DateTime(required=True, data_key='startTime') diff --git a/tests/files/erase-sectors-2-hdd.snapshot.yaml b/tests/files/erase-sectors-2-hdd.snapshot.yaml index 9ce513ad..21e75590 100644 --- a/tests/files/erase-sectors-2-hdd.snapshot.yaml +++ b/tests/files/erase-sectors-2-hdd.snapshot.yaml @@ -75,7 +75,7 @@ ], "type": "EraseBasic", "severity": "Info", - "zeros": false, + "startTime": "2018-07-13T10:52:45.092612" }, { @@ -113,7 +113,6 @@ ], "type": "EraseBasic", "severity": "Info", - "zeros": false, "startTime": "2018-07-13T11:54:55.100667" }, { diff --git a/tests/files/erase-sectors.snapshot.yaml b/tests/files/erase-sectors.snapshot.yaml index ff01f3db..4331352e 100644 --- a/tests/files/erase-sectors.snapshot.yaml +++ b/tests/files/erase-sectors.snapshot.yaml @@ -16,7 +16,6 @@ components: manufacturer: c1mr events: - type: EraseSectors - zeros: True startTime: 2018-06-01T08:12:06 endTime: 2018-06-01T09:12:06 steps: @@ -24,7 +23,7 @@ components: severity: Info startTime: 2018-06-01T08:15:00 endTime: 2018-06-01T09:16:00 - - type: StepZero + - type: StepRandom severity: Info startTime: 2018-06-01T08:16:00 endTime: 2018-06-01T09:17:00 diff --git a/tests/files/workbench-server-3.erase.yaml b/tests/files/workbench-server-3.erase.yaml index 913786be..94197840 100644 --- a/tests/files/workbench-server-3.erase.yaml +++ b/tests/files/workbench-server-3.erase.yaml @@ -10,7 +10,6 @@ type: 'EraseSectors' severity: Info # snapshot: None fulfill! # device: None fulfill! -zeros: False startTime: 2018-01-01T10:10:10 endTime: 2018-01-01T12:10:10 steps: diff --git a/tests/test_basic.py b/tests/test_basic.py index 6c011238..af50e867 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -40,4 +40,4 @@ def test_api_docs(client: Client): 'scheme': 'basic', 'name': 'Authorization' } - assert 94 == len(docs['definitions']) + assert 95 == len(docs['definitions']) diff --git a/tests/test_event.py b/tests/test_event.py index 9d962846..68824d27 100644 --- a/tests/test_event.py +++ b/tests/test_event.py @@ -10,6 +10,7 @@ from teal.enums import Currency, Subdivision from ereuse_devicehub.client import UserClient from ereuse_devicehub.db import db +from ereuse_devicehub.resources import enums from ereuse_devicehub.resources.device import states from ereuse_devicehub.resources.device.models import Desktop, Device, GraphicCard, HardDrive, \ RamModule, SolidStateDrive @@ -40,7 +41,10 @@ def test_author(): def test_erase_basic(): erasure = models.EraseBasic( device=HardDrive(serial_number='foo', manufacturer='bar', model='foo-bar'), - zeros=True, + steps=[ + models.StepZero(**conftest.T), + models.StepRandom(**conftest.T) + ], **conftest.T ) db.session.add(erasure) @@ -48,6 +52,7 @@ def test_erase_basic(): db_erasure = models.EraseBasic.query.one() assert erasure == db_erasure assert next(iter(db_erasure.device.events)) == erasure + assert not erasure.standards, 'EraseBasic themselves do not have standards' @pytest.mark.usefixtures(conftest.auth_app_context.__name__) @@ -65,14 +70,13 @@ def test_validate_device_data_storage(): @pytest.mark.usefixtures(conftest.auth_app_context.__name__) -def test_erase_sectors_steps(): +def test_erase_sectors_steps_erasure_standards_hmg_is5(): erasure = models.EraseSectors( device=SolidStateDrive(serial_number='foo', manufacturer='bar', model='foo-bar'), - zeros=True, steps=[ models.StepZero(**conftest.T), models.StepRandom(**conftest.T), - models.StepZero(**conftest.T) + models.StepRandom(**conftest.T) ], **conftest.T ) @@ -83,6 +87,7 @@ def test_erase_sectors_steps(): assert db_erasure.steps[0].num == 0 assert db_erasure.steps[1].num == 1 assert db_erasure.steps[2].num == 2 + assert {enums.ErasureStandards.HMG_IS5} == erasure.standards @pytest.mark.usefixtures(conftest.auth_app_context.__name__) @@ -324,14 +329,14 @@ def test_ereuse_price(): # Range.verylow not returning nothing -@pytest.mark.xfail(reson='Develop functionality') -def test_erase_standards(): - pass - - -@pytest.mark.xfail(reson='Develop test') +@pytest.mark.usefixtures(conftest.auth_app_context.__name__) def test_erase_physical(): - pass + erasure = models.ErasePhysical( + device=HardDrive(serial_number='foo', manufacturer='bar', model='foo-bar'), + method=enums.PhysicalErasureMethod.Disintegration + ) + db.session.add(erasure) + db.session.commit() @pytest.mark.xfail(reson='validate use-case') diff --git a/tests/test_snapshot.py b/tests/test_snapshot.py index 53f6fd97..c217bf2b 100644 --- a/tests/test_snapshot.py +++ b/tests/test_snapshot.py @@ -289,7 +289,7 @@ def test_snapshot_component_containing_components(user: UserClient): user.post(s, res=Snapshot, status=ValidationError) -def test_erase_privacy(user: UserClient): +def test_erase_privacy_standards(user: UserClient): """Tests a Snapshot with EraseSectors and the resulting privacy properties. """ @@ -310,10 +310,14 @@ def test_erase_privacy(user: UserClient): assert erasure['steps'][1]['startTime'] == '2018-06-01T08:16:00+00:00' assert erasure['steps'][1]['endTime'] == '2018-06-01T09:17:00+00:00' assert erasure['device']['id'] == storage['id'] - for step in erasure['steps']: - assert step['type'] == 'StepZero' - assert step['severity'] == 'Info' - assert 'num' not in step + step1, step2 = erasure['steps'] + assert step1['type'] == 'StepZero' + assert step1['severity'] == 'Info' + assert 'num' not in step1 + assert step2['type'] == 'StepRandom' + assert step2['severity'] == 'Info' + assert 'num' not in step2 + assert ['HMG_IS5'] == erasure['standards'] assert storage['privacy']['type'] == 'EraseSectors' pc, _ = user.get(res=m.Device, item=snapshot['device']['id']) assert pc['privacy'] == [storage['privacy']] diff --git a/tests/test_workbench.py b/tests/test_workbench.py index 5bb23719..d40e3629 100644 --- a/tests/test_workbench.py +++ b/tests/test_workbench.py @@ -263,7 +263,6 @@ def test_snapshot_real_eee_1001pxd(user: UserClient): erase = next(e for e in hdd['events'] if e['type'] == em.EraseBasic.t) assert erase['endTime'] assert erase['startTime'] - assert erase['zeros'] is False assert erase['severity'] == 'Info' assert hdd['privacy'] == 'EraseBasic' mother = components[8]