From 7db879e189ee85c831e5f7386a3c5030fdd17596 Mon Sep 17 00:00:00 2001 From: sergio_gimenez Date: Mon, 4 Nov 2024 08:20:37 +0100 Subject: [PATCH 1/9] Add get_serial_number method --- device/models.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/device/models.py b/device/models.py index a351a11..4e0778f 100644 --- a/device/models.py +++ b/device/models.py @@ -29,7 +29,7 @@ class Device: self.shortid = self.pk[:6].upper() self.algorithm = None self.owner = None - self.annotations = [] + self.annotations = [] self.hids = [] self.uuids = [] self.evidences = [] @@ -108,7 +108,7 @@ class Device: return annotation = annotations.first() self.last_evidence = Evidence(annotation.uuid) - + def is_eraseserver(self): if not self.uuids: self.get_uuids() @@ -120,7 +120,7 @@ class Device: owner=self.owner, type=Annotation.Type.ERASE_SERVER ).first() - + if annotation: return True return False @@ -129,7 +129,8 @@ class Device: return self.uuids[0] def get_lots(self): - self.lots = [x.lot for x in DeviceLot.objects.filter(device_id=self.id)] + self.lots = [ + x.lot for x in DeviceLot.objects.filter(device_id=self.id)] @classmethod def get_unassigned(cls, institution, offset=0, limit=None): @@ -179,7 +180,6 @@ class Device: count = cls.get_unassigned_count(institution) return devices, count - @classmethod def get_unassigned_count(cls, institution): @@ -279,6 +279,12 @@ class Device: self.get_last_evidence() return self.last_evidence.get_manufacturer() + @property + def serial_number(self): + if not self.last_evidence: + self.get_last_evidence() + return self.last_evidence.get_serial_number() + @property def type(self): if self.last_evidence.doc['type'] == "WebSnapshot": From 8cb66104cab8108f1301109d37dcd2c37bf6833c Mon Sep 17 00:00:00 2001 From: sergio_gimenez Date: Mon, 4 Nov 2024 08:21:01 +0100 Subject: [PATCH 2/9] Add get_serial_number() method --- evidence/models.py | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/evidence/models.py b/evidence/models.py index fef6a92..a34be69 100644 --- a/evidence/models.py +++ b/evidence/models.py @@ -11,7 +11,7 @@ from user.models import User, Institution class Annotation(models.Model): class Type(models.IntegerChoices): - SYSTEM= 0, "System" + SYSTEM = 0, "System" USER = 1, "User" DOCUMENT = 2, "Document" ERASE_SERVER = 3, "EraseServer" @@ -19,14 +19,16 @@ class Annotation(models.Model): created = models.DateTimeField(auto_now_add=True) uuid = models.UUIDField() owner = models.ForeignKey(Institution, on_delete=models.CASCADE) - user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True) - type = models.SmallIntegerField(choices=Type) + user = models.ForeignKey( + User, on_delete=models.SET_NULL, null=True, blank=True) + type = models.SmallIntegerField(choices=Type) key = models.CharField(max_length=STR_EXTEND_SIZE) value = models.CharField(max_length=STR_EXTEND_SIZE) class Meta: constraints = [ - models.UniqueConstraint(fields=["type", "key", "uuid"], name="unique_type_key_uuid") + models.UniqueConstraint( + fields=["type", "key", "uuid"], name="unique_type_key_uuid") ] @@ -37,8 +39,8 @@ class Evidence: self.doc = None self.created = None self.dmi = None - self.annotations = [] - self.components = [] + self.annotations = [] + self.components = [] self.default = "n/a" self.get_owner() @@ -87,7 +89,7 @@ class Evidence: return self.components def get_manufacturer(self): - if self.doc.get("type") == "WebSnapshot": + if self.is_new_snapshot(): kv = self.doc.get('kv', {}) if len(kv) < 1: return "" @@ -99,7 +101,7 @@ class Evidence: return self.dmi.manufacturer().strip() def get_model(self): - if self.doc.get("type") == "WebSnapshot": + if self.is_new_snapshot(): kv = self.doc.get('kv', {}) if len(kv) < 2: return "" @@ -122,6 +124,11 @@ class Evidence: return k return "" + def get_serial_number(self): + if self.is_legacy(): + return self.doc['device']['serialNumber'] + return self.dmi.serial_number().strip() + @classmethod def get_all(cls, user): return Annotation.objects.filter( @@ -136,3 +143,6 @@ class Evidence: def is_legacy(self): return self.doc.get("software") != "workbench-script" + + def is_new_snapshot(self): + return self.doc.get("type") == "WebSnapshot" From 915d95379cdcd01dc085383328ca9eaefea1a338 Mon Sep 17 00:00:00 2001 From: sergio_gimenez Date: Mon, 4 Nov 2024 08:21:19 +0100 Subject: [PATCH 3/9] Render serial number in details view --- device/templates/details.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/device/templates/details.html b/device/templates/details.html index 8477948..331c857 100644 --- a/device/templates/details.html +++ b/device/templates/details.html @@ -84,7 +84,7 @@
{% trans 'Serial Number' %}
-
{{ object.last_evidence.doc.device.serialNumber|default:'' }}
+
{{ object.serial_number|default:'' }}
{% endif %} From 033e4df29780a7e95f2ab9d534994486bdc3bdc7 Mon Sep 17 00:00:00 2001 From: sergio_gimenez Date: Mon, 4 Nov 2024 08:24:23 +0100 Subject: [PATCH 4/9] Render serial number in public website --- device/templates/device_web.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/device/templates/device_web.html b/device/templates/device_web.html index 21ca570..0008e49 100644 --- a/device/templates/device_web.html +++ b/device/templates/device_web.html @@ -122,7 +122,7 @@
Serial Number
-
{{ object.last_evidence.doc.device.serialNumber|default:'' }}
+
{{object.serial_number|default:'' }}
{% endif %} From e6c42a908f09c19354084a5200ff54fcee518123 Mon Sep 17 00:00:00 2001 From: sergio_gimenez Date: Tue, 5 Nov 2024 10:19:24 +0100 Subject: [PATCH 5/9] Show components and serials only if user is authenticated --- device/templates/device_web.html | 48 +++++++++++++++++--------------- device/views.py | 28 +++++++++++++++---- 2 files changed, 47 insertions(+), 29 deletions(-) diff --git a/device/templates/device_web.html b/device/templates/device_web.html index 0008e49..f63eb9d 100644 --- a/device/templates/device_web.html +++ b/device/templates/device_web.html @@ -120,10 +120,12 @@
Model
{{ object.model|default:'' }}
-
-
Serial Number
-
{{object.serial_number|default:'' }}
-
+ {% if user.is_authenticated %} +
+
Serial Number
+
{{ object.serial_number|default:'' }}
+
+ {% endif %} {% endif %} @@ -136,28 +138,28 @@ {% endfor %} - -

Components

-
- {% for component in object.components %} -
-
-
-
{{ component.type }}
-

- {% for component_key, component_value in component.items %} - {% if component_key not in 'actions,type' %} - {{ component_key }}: {{ component_value }}
- {% endif %} - {% endfor %} -

+ {% if user.is_authenticated %} +

Components

+
+ {% for component in object.components %} +
+
+
+
{{ component.type }}
+

+ {% for component_key, component_value in component.items %} + {% if component_key not in 'actions,type' %} + {{ component_key }}: {{ component_value }}
+ {% endif %} + {% endfor %} +

+
-
- {% endfor %} -
+ {% endfor %} +
+ {% endif %}
-

©{% now 'Y' %} eReuse. All rights reserved. diff --git a/device/views.py b/device/views.py index 90b43e8..f0a0097 100644 --- a/device/views.py +++ b/device/views.py @@ -117,10 +117,10 @@ class PublicDeviceWebView(TemplateView): def get(self, request, *args, **kwargs): self.pk = kwargs['pk'] self.object = Device(id=self.pk) - + if not self.object.last_evidence: raise Http404 - + if self.request.headers.get('Accept') == 'application/json': return self.get_json_response() return super().get(request, *args, **kwargs) @@ -133,15 +133,31 @@ class PublicDeviceWebView(TemplateView): }) return context - def get_json_response(self): - data = { + @property + def public_fields(self): + return { 'id': self.object.id, 'shortid': self.object.shortid, 'uuids': self.object.uuids, 'hids': self.object.hids, - 'components': self.object.components } - return JsonResponse(data) + + @property + def authenticated_fields(self): + return { + 'components': self.object.components, + 'serial_number': self.object.serial_number + } + + def get_device_data(self): + data = self.public_fields + if self.request.user.is_authenticated: + data.update(self.authenticated_fields) + return data + + def get_json_response(self): + device_data = self.get_device_data() + return JsonResponse(device_data) class AddAnnotationView(DashboardView, CreateView): From 51a2e74f7fc2f5d72221934672af346efad428a4 Mon Sep 17 00:00:00 2001 From: sergio_gimenez Date: Tue, 5 Nov 2024 10:19:35 +0100 Subject: [PATCH 6/9] [WIP] unit tests --- device/tests/test_public_device_web.py | 89 ++++++++++++++++++++++++-- 1 file changed, 83 insertions(+), 6 deletions(-) diff --git a/device/tests/test_public_device_web.py b/device/tests/test_public_device_web.py index 33efe05..149e4e8 100644 --- a/device/tests/test_public_device_web.py +++ b/device/tests/test_public_device_web.py @@ -3,6 +3,7 @@ from django.urls import reverse from unittest.mock import patch from device.views import PublicDeviceWebView from device.tests.test_mock_device import TestDevice, TestWebSnapshotDevice +from user.models import User, Institution # Import both models class PublicDeviceWebViewTests(TestCase): @@ -11,6 +12,14 @@ class PublicDeviceWebViewTests(TestCase): self.test_id = "test123" self.test_url = reverse('device:device_web', kwargs={'pk': self.test_id}) + self.institution = Institution.objects.create( + name="Test Institution" + ) + self.user = User.objects.create_user( + email='test@example.com', + institution=self.institution, + password='testpass123' + ) def test_url_resolves_correctly(self): """Test that the URL is constructed correctly""" @@ -18,28 +27,52 @@ class PublicDeviceWebViewTests(TestCase): self.assertEqual(url, f'/device/{self.test_id}/public/') @patch('device.views.Device') - def test_html_response(self, MockDevice): + def test_html_response_anonymous(self, MockDevice): test_device = TestDevice(id=self.test_id) MockDevice.return_value = test_device response = self.client.get(self.test_url) - self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'device_web.html') - self.assertContains(response, 'Test Manufacturer') self.assertContains(response, 'Test Model') self.assertContains(response, 'Computer') self.assertContains(response, self.test_id) + self.assertNotContains(response, 'Serial Number') + self.assertNotContains(response, 'Components') + self.assertNotContains(response, 'CPU') + self.assertNotContains(response, 'Intel') + self.assertNotContains(response, 'RAM') + self.assertNotContains(response, 'Kingston') + @patch('device.views.Device') + def test_html_response_authenticated(self, MockDevice): + test_device = TestDevice(id=self.test_id) + MockDevice.return_value = test_device + self.client.login(username='test@example.com', password='testpass123') + response = self.client.get(self.test_url) + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'device_web.html') + self.assertContains(response, 'Test Manufacturer') + self.assertContains(response, 'Test Model') + self.assertContains(response, 'Computer') + self.assertContains(response, self.test_id) + self.assertContains(response, 'Serial Number') + self.assertContains(response, 'Components') self.assertContains(response, 'CPU') self.assertContains(response, 'Intel') self.assertContains(response, 'RAM') self.assertContains(response, 'Kingston') @patch('device.views.Device') - def test_json_response(self, MockDevice): + def test_json_response_anonymous(self, MockDevice): test_device = TestDevice(id=self.test_id) - MockDevice.return_value = test_device + test_device.get_last_evidence() + mock_instance = MockDevice.return_value + mock_instance.id = self.test_id + mock_instance.shortid = self.test_id[:6].upper() + mock_instance.uuids = [] + mock_instance.hids = ['hid1', 'hid2'] + mock_instance.last_evidence = test_device.last_evidence response = self.client.get( self.test_url, @@ -52,7 +85,51 @@ class PublicDeviceWebViewTests(TestCase): json_data = response.json() self.assertEqual(json_data['id'], self.test_id) self.assertEqual(json_data['shortid'], self.test_id[:6].upper()) - self.assertEqual(json_data['components'], test_device.components) + self.assertEqual(json_data['uuids'], []) + self.assertEqual(json_data['hids'], ['hid1', 'hid2']) + self.assertNotIn('components', json_data) + self.assertNotIn('serial_number', json_data) + + @patch('device.views.Device') + def test_json_response_authenticated(self, MockDevice): + test_device = TestDevice(id=self.test_id) + test_device.get_last_evidence() + mock_instance = MockDevice.return_value + mock_instance.id = self.test_id + mock_instance.shortid = self.test_id[:6].upper() + mock_instance.uuids = [] + mock_instance.hids = ['hid1', 'hid2'] + mock_instance.last_evidence = test_device.last_evidence + mock_instance.components = test_device.last_evidence.get_components() + mock_instance.serial_number = test_device.last_evidence.doc['device']['serialNumber'] + + self.client.login(username='test@example.com', password='testpass123') + response = self.client.get( + self.test_url, + HTTP_ACCEPT='application/json' + ) + + self.assertEqual(response.status_code, 200) + self.assertEqual(response['Content-Type'], 'application/json') + + json_data = response.json() + self.assertEqual(json_data['id'], self.test_id) + self.assertEqual(json_data['shortid'], self.test_id[:6].upper()) + self.assertEqual(json_data['components'], [ + { + 'type': 'CPU', + 'model': 'Intel i7', + 'manufacturer': 'Intel' + }, + { + 'type': 'RAM', + 'size': '8GB', + 'manufacturer': 'Kingston' + } + ]) + self.assertEqual(json_data['serial_number'], 'SN123456') + self.assertEqual(json_data['uuids'], []) + self.assertEqual(json_data['hids'], ['hid1', 'hid2']) @patch('device.views.Device') def test_websnapshot_device(self, MockDevice): From a68403b05aaceb31405cf6d65b4a267272987746 Mon Sep 17 00:00:00 2001 From: sergio_gimenez Date: Tue, 5 Nov 2024 10:26:21 +0100 Subject: [PATCH 7/9] better organise code --- device/tests/test_mock_device.py | 103 +++++++++---------------- device/tests/test_public_device_web.py | 40 +--------- 2 files changed, 41 insertions(+), 102 deletions(-) diff --git a/device/tests/test_mock_device.py b/device/tests/test_mock_device.py index a3fe019..efe8a5c 100644 --- a/device/tests/test_mock_device.py +++ b/device/tests/test_mock_device.py @@ -3,74 +3,45 @@ from unittest.mock import MagicMock class TestDevice(Device): - """A test subclass of Device that overrides the database-dependent methods""" - # TODO Leaving commented bc not used, but might be useful at some point - # def get_annotations(self): - # """Return empty list instead of querying database""" - # return [] + def __init__(self, id): + super().__init__(id=id) + self.shortid = id[:6].upper() + self.uuids = [] + self.hids = ['hid1', 'hid2'] + self._setup_evidence() - # def get_uuids(self): - # """Set uuids directly instead of querying""" - # self.uuids = ['uuid1', 'uuid2'] - - # def get_hids(self): - # """Set hids directly instead of querying""" - # self.hids = ['hid1', 'hid2'] - - # def get_evidences(self): - # """Set evidences directly instead of querying""" - # self.evidences = [] - - # def get_lots(self): - # """Set lots directly instead of querying""" - # self.lots = [] - - def get_last_evidence(self): - if not hasattr(self, '_evidence'): - self._evidence = MagicMock() - self._evidence.doc = { - 'type': 'Computer', - 'manufacturer': 'Test Manufacturer', - 'model': 'Test Model', - 'device': { - 'serialNumber': 'SN123456', - 'type': 'Computer' - } + def _setup_evidence(self): + self._evidence = MagicMock() + self._evidence.doc = { + 'type': 'Computer', + 'manufacturer': 'Test Manufacturer', + 'model': 'Test Model', + 'device': { + 'serialNumber': 'SN123456', + 'type': 'Computer' } - self._evidence.get_manufacturer = lambda: 'Test Manufacturer' - self._evidence.get_model = lambda: 'Test Model' - self._evidence.get_chassis = lambda: 'Computer' - self._evidence.get_components = lambda: [ - { - 'type': 'CPU', - 'model': 'Intel i7', - 'manufacturer': 'Intel' - }, - { - 'type': 'RAM', - 'size': '8GB', - 'manufacturer': 'Kingston' - } - ] + } + self._evidence.get_manufacturer = lambda: 'Test Manufacturer' + self._evidence.get_model = lambda: 'Test Model' + self._evidence.get_chassis = lambda: 'Computer' + self._evidence.get_components = lambda: [ + { + 'type': 'CPU', + 'model': 'Intel i7', + 'manufacturer': 'Intel' + }, + { + 'type': 'RAM', + 'size': '8GB', + 'manufacturer': 'Kingston' + } + ] self.last_evidence = self._evidence + @property + def components(self): + return self.last_evidence.get_components() -class TestWebSnapshotDevice(TestDevice): - """A test subclass of Device that simulates a WebSnapshot device""" - - def get_last_evidence(self): - if not hasattr(self, '_evidence'): - self._evidence = MagicMock() - self._evidence.doc = { - 'type': 'WebSnapshot', - 'kv': { - 'URL': 'http://example.com', - 'Title': 'Test Page', - 'Timestamp': '2024-01-01' - }, - 'device': { - 'type': 'Laptop' - } - } - self.last_evidence = self._evidence - return self._evidence + @property + def serial_number(self): + return self.last_evidence.doc['device']['serialNumber'] diff --git a/device/tests/test_public_device_web.py b/device/tests/test_public_device_web.py index 149e4e8..1a0b3fc 100644 --- a/device/tests/test_public_device_web.py +++ b/device/tests/test_public_device_web.py @@ -2,8 +2,8 @@ from django.test import TestCase, Client from django.urls import reverse from unittest.mock import patch from device.views import PublicDeviceWebView -from device.tests.test_mock_device import TestDevice, TestWebSnapshotDevice -from user.models import User, Institution # Import both models +from device.tests.test_mock_device import TestDevice +from user.models import User, Institution class PublicDeviceWebViewTests(TestCase): @@ -22,7 +22,6 @@ class PublicDeviceWebViewTests(TestCase): ) def test_url_resolves_correctly(self): - """Test that the URL is constructed correctly""" url = reverse('device:device_web', kwargs={'pk': self.test_id}) self.assertEqual(url, f'/device/{self.test_id}/public/') @@ -66,22 +65,13 @@ class PublicDeviceWebViewTests(TestCase): @patch('device.views.Device') def test_json_response_anonymous(self, MockDevice): test_device = TestDevice(id=self.test_id) - test_device.get_last_evidence() - mock_instance = MockDevice.return_value - mock_instance.id = self.test_id - mock_instance.shortid = self.test_id[:6].upper() - mock_instance.uuids = [] - mock_instance.hids = ['hid1', 'hid2'] - mock_instance.last_evidence = test_device.last_evidence - + MockDevice.return_value = test_device response = self.client.get( self.test_url, HTTP_ACCEPT='application/json' ) - self.assertEqual(response.status_code, 200) self.assertEqual(response['Content-Type'], 'application/json') - json_data = response.json() self.assertEqual(json_data['id'], self.test_id) self.assertEqual(json_data['shortid'], self.test_id[:6].upper()) @@ -93,22 +83,12 @@ class PublicDeviceWebViewTests(TestCase): @patch('device.views.Device') def test_json_response_authenticated(self, MockDevice): test_device = TestDevice(id=self.test_id) - test_device.get_last_evidence() - mock_instance = MockDevice.return_value - mock_instance.id = self.test_id - mock_instance.shortid = self.test_id[:6].upper() - mock_instance.uuids = [] - mock_instance.hids = ['hid1', 'hid2'] - mock_instance.last_evidence = test_device.last_evidence - mock_instance.components = test_device.last_evidence.get_components() - mock_instance.serial_number = test_device.last_evidence.doc['device']['serialNumber'] - + MockDevice.return_value = test_device self.client.login(username='test@example.com', password='testpass123') response = self.client.get( self.test_url, HTTP_ACCEPT='application/json' ) - self.assertEqual(response.status_code, 200) self.assertEqual(response['Content-Type'], 'application/json') @@ -130,15 +110,3 @@ class PublicDeviceWebViewTests(TestCase): self.assertEqual(json_data['serial_number'], 'SN123456') self.assertEqual(json_data['uuids'], []) self.assertEqual(json_data['hids'], ['hid1', 'hid2']) - - @patch('device.views.Device') - def test_websnapshot_device(self, MockDevice): - test_device = TestWebSnapshotDevice(id=self.test_id) - MockDevice.return_value = test_device - response = self.client.get(self.test_url) - - self.assertEqual(response.status_code, 200) - self.assertTemplateUsed(response, 'device_web.html') - - self.assertContains(response, 'http://example.com') - self.assertContains(response, 'Test Page') From 26c3401f4d74a1c4dbcf47b8d069bcc560ecbd74 Mon Sep 17 00:00:00 2001 From: sergio_gimenez Date: Wed, 6 Nov 2024 08:24:10 +0100 Subject: [PATCH 8/9] Do not show serial numbers if user not authenticated --- device/templates/device_web.html | 36 +++++++++++++------------- device/tests/test_mock_device.py | 6 +++-- device/tests/test_public_device_web.py | 14 +++++----- device/views.py | 9 ++++++- 4 files changed, 36 insertions(+), 29 deletions(-) diff --git a/device/templates/device_web.html b/device/templates/device_web.html index f63eb9d..8c607d3 100644 --- a/device/templates/device_web.html +++ b/device/templates/device_web.html @@ -138,31 +138,31 @@ {% endfor %}

- {% if user.is_authenticated %} -

Components

-
- {% for component in object.components %} -
-
-
-
{{ component.type }}
-

- {% for component_key, component_value in component.items %} - {% if component_key not in 'actions,type' %} +

Components

+
+ {% for component in object.components %} +
+
+
+
{{ component.type }}
+

+ {% for component_key, component_value in component.items %} + {% if component_key not in 'actions,type' %} + {% if component_key != 'serialNumber' or user.is_authenticated %} {{ component_key }}: {{ component_value }}
{% endif %} - {% endfor %} -

-
+ {% endif %} + {% endfor %} +

- {% endfor %} -
- {% endif %} +
+ {% endfor %} +

- ©{% now 'Y' %} eReuse. All rights reserved. + ©{% now 'Y' %}eReuse. All rights reserved.

diff --git a/device/tests/test_mock_device.py b/device/tests/test_mock_device.py index efe8a5c..732c6ed 100644 --- a/device/tests/test_mock_device.py +++ b/device/tests/test_mock_device.py @@ -28,12 +28,14 @@ class TestDevice(Device): { 'type': 'CPU', 'model': 'Intel i7', - 'manufacturer': 'Intel' + 'manufacturer': 'Intel', + 'serialNumber': 'SN12345678' }, { 'type': 'RAM', 'size': '8GB', - 'manufacturer': 'Kingston' + 'manufacturer': 'Kingston', + 'serialNumber': 'SN87654321' } ] self.last_evidence = self._evidence diff --git a/device/tests/test_public_device_web.py b/device/tests/test_public_device_web.py index 1a0b3fc..84d8bf1 100644 --- a/device/tests/test_public_device_web.py +++ b/device/tests/test_public_device_web.py @@ -37,11 +37,7 @@ class PublicDeviceWebViewTests(TestCase): self.assertContains(response, 'Computer') self.assertContains(response, self.test_id) self.assertNotContains(response, 'Serial Number') - self.assertNotContains(response, 'Components') - self.assertNotContains(response, 'CPU') - self.assertNotContains(response, 'Intel') - self.assertNotContains(response, 'RAM') - self.assertNotContains(response, 'Kingston') + self.assertNotContains(response, 'serialNumber') @patch('device.views.Device') def test_html_response_authenticated(self, MockDevice): @@ -77,8 +73,8 @@ class PublicDeviceWebViewTests(TestCase): self.assertEqual(json_data['shortid'], self.test_id[:6].upper()) self.assertEqual(json_data['uuids'], []) self.assertEqual(json_data['hids'], ['hid1', 'hid2']) - self.assertNotIn('components', json_data) self.assertNotIn('serial_number', json_data) + self.assertNotIn('serialNumber', json_data) @patch('device.views.Device') def test_json_response_authenticated(self, MockDevice): @@ -99,12 +95,14 @@ class PublicDeviceWebViewTests(TestCase): { 'type': 'CPU', 'model': 'Intel i7', - 'manufacturer': 'Intel' + 'manufacturer': 'Intel', + 'serialNumber': 'SN12345678' }, { 'type': 'RAM', 'size': '8GB', - 'manufacturer': 'Kingston' + 'manufacturer': 'Kingston', + 'serialNumber': 'SN87654321' } ]) self.assertEqual(json_data['serial_number'], 'SN123456') diff --git a/device/views.py b/device/views.py index f0a0097..f99c196 100644 --- a/device/views.py +++ b/device/views.py @@ -140,15 +140,22 @@ class PublicDeviceWebView(TemplateView): 'shortid': self.object.shortid, 'uuids': self.object.uuids, 'hids': self.object.hids, + 'components': self.remove_serial_numnber_from(self.object.components), } @property def authenticated_fields(self): return { + 'serial_number': self.object.serial_number, 'components': self.object.components, - 'serial_number': self.object.serial_number } + def remove_serial_numnber_from(self, components): + for component in components: + if 'serial_number' in component: + del component['SerialNumber'] + return components + def get_device_data(self): data = self.public_fields if self.request.user.is_authenticated: From 6212075852fa258d376113fb52b3c65e6f9ccc01 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 6 Nov 2024 17:21:48 +0100 Subject: [PATCH 9/9] fix names --- device/views.py | 4 ++-- evidence/models.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/device/views.py b/device/views.py index f99c196..319f8cf 100644 --- a/device/views.py +++ b/device/views.py @@ -140,7 +140,7 @@ class PublicDeviceWebView(TemplateView): 'shortid': self.object.shortid, 'uuids': self.object.uuids, 'hids': self.object.hids, - 'components': self.remove_serial_numnber_from(self.object.components), + 'components': self.remove_serial_number_from(self.object.components), } @property @@ -150,7 +150,7 @@ class PublicDeviceWebView(TemplateView): 'components': self.object.components, } - def remove_serial_numnber_from(self, components): + def remove_serial_number_from(self, components): for component in components: if 'serial_number' in component: del component['SerialNumber'] diff --git a/evidence/models.py b/evidence/models.py index a34be69..e9af092 100644 --- a/evidence/models.py +++ b/evidence/models.py @@ -89,7 +89,7 @@ class Evidence: return self.components def get_manufacturer(self): - if self.is_new_snapshot(): + if self.is_web_snapshot(): kv = self.doc.get('kv', {}) if len(kv) < 1: return "" @@ -101,7 +101,7 @@ class Evidence: return self.dmi.manufacturer().strip() def get_model(self): - if self.is_new_snapshot(): + if self.is_web_snapshot(): kv = self.doc.get('kv', {}) if len(kv) < 2: return "" @@ -144,5 +144,5 @@ class Evidence: def is_legacy(self): return self.doc.get("software") != "workbench-script" - def is_new_snapshot(self): + def is_web_snapshot(self): return self.doc.get("type") == "WebSnapshot"