diff --git a/src/ralph/security/api.py b/src/ralph/security/api.py index f80fe9da28..0743cd0ae9 100644 --- a/src/ralph/security/api.py +++ b/src/ralph/security/api.py @@ -39,11 +39,11 @@ def to_internal_value(self, data): # external_id to local_id if 'external_vulnerabilities' in data: - external_ids = data.get('external_vulnerabilities', []) + external_ids = set(data.get('external_vulnerabilities', [])) converted = Vulnerability.objects.filter( external_vulnerability_id__in=external_ids) if len(converted) != len(external_ids): - unknown = set(external_ids) - set( + unknown = external_ids - set( [str(v.external_vulnerability_id) for v in converted] ) msg = "Unknow external_vulnerabilities: {}".format( diff --git a/src/ralph/security/migrations/0003_auto_20170110_1352.py b/src/ralph/security/migrations/0003_auto_20170110_1352.py new file mode 100644 index 0000000000..75eb5c1490 --- /dev/null +++ b/src/ralph/security/migrations/0003_auto_20170110_1352.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('security', '0002_auto_20160307_1138'), + ] + + operations = [ + migrations.AlterField( + model_name='securityscan', + name='vulnerabilities', + field=models.ManyToManyField(blank=True, to='security.Vulnerability'), + ), + ] diff --git a/src/ralph/security/models.py b/src/ralph/security/models.py index eb9fc3cd30..31894c6b52 100644 --- a/src/ralph/security/models.py +++ b/src/ralph/security/models.py @@ -62,4 +62,4 @@ class SecurityScan( details_url = models.URLField(max_length=255, blank=True) rescan_url = models.URLField(blank=True, verbose_name=_('Rescan url')) base_object = models.ForeignKey(BaseObject) - vulnerabilities = models.ManyToManyField(Vulnerability) + vulnerabilities = models.ManyToManyField(Vulnerability, blank=True) diff --git a/src/ralph/security/tests/test_api.py b/src/ralph/security/tests/test_api.py index 2bfb2b8e7e..1147fffe33 100644 --- a/src/ralph/security/tests/test_api.py +++ b/src/ralph/security/tests/test_api.py @@ -251,12 +251,24 @@ def test_create_scan_by_external_id_works(self): self.vulnerability.id, security_scan.vulnerabilities.get().id ) - def test_create_scan_raise_error_when_both_vulnerabilities_empty(self): - self.data['external_vulnerabilities'] = [] + def test_create_scan_by_duplicated_external_id_works(self): + self.data['external_vulnerabilities'] = [ + self.vulnerability.external_vulnerability_id, + self.vulnerability.external_vulnerability_id + ] response = self.client.post( reverse('securityscan-list'), self.data, format='json' ) + security_scan = SecurityScan.objects.get(pk=response.data['id']) + self.assertEqual(security_scan.vulnerabilities.count(), 1) self.assertEqual( - response.data, - {'vulnerabilities': ['This list may not be empty.']}, + self.vulnerability.id, security_scan.vulnerabilities.get().id ) + + def test_create_scan_works_when_both_vulnerabilities_empty(self): + self.data['external_vulnerabilities'] = [] + response = self.client.post( + reverse('securityscan-list'), self.data, format='json' + ) + security_scan = SecurityScan.objects.get(pk=response.data['id']) + self.assertEqual(security_scan.vulnerabilities.count(), 0)