diff --git a/ereuse_devicehub/inventory/views.py b/ereuse_devicehub/inventory/views.py index c00a8cb1..3f4a52e3 100644 --- a/ereuse_devicehub/inventory/views.py +++ b/ereuse_devicehub/inventory/views.py @@ -47,6 +47,7 @@ from ereuse_devicehub.resources.device.models import ( Computer, DataStorage, Device, + Mobile, Placeholder, ) from ereuse_devicehub.resources.documents.device_row import ActionRow, DeviceRow @@ -1198,6 +1199,10 @@ class ExportsView(View): ac = device.last_erase_action if ac: erasures.append(ac) + elif isinstance(device, Mobile): + ac = device.last_erase_action + if ac: + erasures.append(ac) return erasures def get_costum_details(self, erasures): @@ -1241,15 +1246,19 @@ class ExportsView(View): def get_server_erasure_hosts(self, erasures): erasures_host = [] + erasures_mobile = [] erasures_on_server = [] for erase in erasures: try: + if isinstance(erase.device, Mobile): + erasures_mobile.append(erase.device) + continue if erase.parent.binding.kangaroo: erasures_host.append(erase.parent) erasures_on_server.append(erase) except Exception: pass - return erasures_host, erasures_on_server + return erasures_host, erasures_on_server, erasures_mobile def build_erasure_certificate(self): erasures = self.get_datastorages() @@ -1261,9 +1270,10 @@ class ExportsView(View): my_data, customer_details = self.get_costum_details(erasures) - a, b = self.get_server_erasure_hosts(erasures) - erasures_host, erasures_on_server = a, b + a, b, c = self.get_server_erasure_hosts(erasures) + erasures_host, erasures_on_server, erasures_mobile = a, b, c erasures_host = set(erasures_host) + erasures_mobile = set(erasures_mobile) result_success = 0 result_failed = 0 @@ -1278,7 +1288,8 @@ class ExportsView(View): erasures_on_server = sorted(erasures_on_server, key=lambda x: x.end_time) erasures_normal = list(set(erasures) - set(erasures_on_server)) erasures_normal = sorted(erasures_normal, key=lambda x: x.end_time) - n_computers = len({x.parent for x in erasures} - erasures_host) + n_computers = len({x.parent for x in erasures if x.parent} - erasures_host) + n_mobiles = len(erasures_mobile) params = { 'title': 'Device Sanitization', @@ -1289,10 +1300,12 @@ class ExportsView(View): 'software': software, 'my_data': my_data, 'n_computers': n_computers, + 'n_mobiles': n_mobiles, 'result_success': result_success, 'result_failed': result_failed, 'customer_details': customer_details, 'erasure_hosts': erasures_host, + 'erasure_mobiles': erasures_mobile, 'erasures_normal': erasures_normal, } return flask.render_template('inventory/erasure.html', **params) diff --git a/ereuse_devicehub/resources/device/models.py b/ereuse_devicehub/resources/device/models.py index e6662f26..ca7ea9be 100644 --- a/ereuse_devicehub/resources/device/models.py +++ b/ereuse_devicehub/resources/device/models.py @@ -1066,6 +1066,9 @@ class Device(Thing): return lot return None + def is_mobile(self): + return isinstance(self, Mobile) + def __lt__(self, other): return self.id < other.id @@ -1375,11 +1378,11 @@ class Computer(Device): @property def external_document_erasure(self): """Returns the external ``DataStorage`` proof of erasure.""" - from ereuse_devicehub.resources.action.models import DataWipe + from ereuse_devicehub.resources.action.models import EraseDataWipe urls = set() try: - ev = self.last_action_of(DataWipe) + ev = self.last_action_of(EraseDataWipe) urls.add(ev.document.url.to_text()) except LookupError: pass @@ -1490,6 +1493,48 @@ class Mobile(Device): raise ValidationError('{} is not a valid meid.'.format(value)) return value + @property + def last_erase_action(self): + erase_auto = None + erase_manual = None + + if self.binding: + erase_auto = self.privacy + erase_manual = self.binding.device.privacy + if self.placeholder: + erase_manual = self.privacy + if self.placeholder.binding: + erase_auto = self.placeholder.binding.privacy + + if erase_auto and erase_manual: + return ( + erase_auto + if erase_auto.created > erase_manual.created + else erase_manual + ) + if erase_manual: + return erase_manual + if erase_auto: + return erase_auto + return None + + @property + def privacy(self): + """Returns the privacy compliance state of the data storage. + + This is, the last erasure performed to the data storage. + """ + from ereuse_devicehub.resources.action.models import EraseBasic + + try: + ev = self.last_action_of(EraseBasic) + except LookupError: + ev = None + return ev + + def get_size(self): + return self.data_storage_size + class Smartphone(Mobile): pass diff --git a/ereuse_devicehub/resources/documents/device_row.py b/ereuse_devicehub/resources/documents/device_row.py index edb1282f..b9d6c219 100644 --- a/ereuse_devicehub/resources/documents/device_row.py +++ b/ereuse_devicehub/resources/documents/device_row.py @@ -343,6 +343,7 @@ class DeviceRow(BaseDeviceRow): if isinstance(device, d.Mobile): self['IMEI'] = device.imei or '' + self.get_erasure_datawipe_mobile(device) def components(self): """Function to get all components information of a device.""" @@ -417,6 +418,24 @@ class DeviceRow(BaseDeviceRow): self['{} {} Size (MB)'.format(ctype, i)] = none2str(component.size) self['{} {} Speed (MHz)'.format(ctype, i)] = none2str(component.speed) + def get_erasure_datawipe_mobile(self, device): + actions = sorted(device.actions) + erasures = [a for a in actions if a.type == 'EraseDataWipe'] + erasure = erasures[-1] if erasures else None + if erasure: + self['Erasure DataStorage 1'] = none2str(device.chid) + serial_number = none2str(device.imei) + storage_size = none2str(device.data_storage_size) + self['Erasure DataStorage 1 Serial Number'] = serial_number + self['Erasure DataStorage 1 Size (MB)'] = storage_size + self['Erasure DataStorage 1 Software'] = erasure.document.software + self['Erasure DataStorage 1 Result'] = get_result(erasure) + self['Erasure DataStorage 1 Type'] = erasure.type + self['Erasure DataStorage 1 Date'] = format(erasure.document.date or '') + self['Erasure DataStorage 1 Certificate URL'] = ( + erasure.document.url and erasure.document.url.to_text() or '' + ) + def get_datastorage(self, ctype, i, component): """Particular fields for component DataStorage. A DataStorage can be HardDrive or SolidStateDrive. @@ -455,6 +474,10 @@ class DeviceRow(BaseDeviceRow): self['Erasure {} {} Size (MB)'.format(ctype, i)] = none2str(component.size) self['Erasure {} {} Software'.format(ctype, i)] = erasure.document.software self['Erasure {} {} Result'.format(ctype, i)] = get_result(erasure) + self['Erasure {} {} Type'.format(ctype, i)] = erasure.type + self['Erasure {} {} Date'.format(ctype, i)] = format( + erasure.document.date or '' + ) self['Erasure {} {} Certificate URL'.format(ctype, i)] = ( erasure.document.url and erasure.document.url.to_text() or '' ) diff --git a/ereuse_devicehub/templates/inventory/erasure.html b/ereuse_devicehub/templates/inventory/erasure.html index 5674ae9c..15ed5db6 100644 --- a/ereuse_devicehub/templates/inventory/erasure.html +++ b/ereuse_devicehub/templates/inventory/erasure.html @@ -209,6 +209,16 @@ {% endif %} + {% if n_mobiles %} + + + N° of mobiles: + + + {{ n_mobiles }} + + + {% endif %} N° of data storage unit(s): @@ -322,12 +332,20 @@ {% for erasure in erasures %} + {% if erasure.device.is_mobile() %} + + {{ (erasure.device.imei or '') }} + + + + {% else %} {{ (erasure.device.serial_number or '').upper() }} {{ (erasure.parent.serial_number or '').upper() }} + {% endif %} {{ erasure.get_public_name() }} @@ -351,12 +369,21 @@

Technical Details

{% endif %} + {% if erasure.device.is_mobile() %} +

{{ (erasure.device.imei or '') }}

+
+
Mobile Drive:
+
Model: {{ erasure.device.model }}
+
IMEI: {{ (erasure.device.imei or '') }}
+
DHID: {{ erasure.device.dhid }}
+
Size: {{ erasure.device.get_size() or '' }}
+ {% else %}

{{ (erasure.device.serial_number or '').upper() }}

Storage Drive:
Model: {{ erasure.device.model }}
SN: {{ (erasure.device.serial_number or '').upper() }}
-
Size: {{ erasure.device.get_size()}}
+
Size: {{ erasure.device.get_size() or '' }}
{% if erasure.parent %}
Computer Host:
@@ -364,6 +391,7 @@
SN: {{ (erasure.parent.serial_number or '').upper() }}
DHID: {{ erasure.parent.dhid }}
{% endif %} + {% endif %}
Erasure: