|
25 | 25 |
|
26 | 26 | from dojo.base_models.base import BaseModel |
27 | 27 | from dojo.finding.cwe import cwe_label, finding_cwe_labels |
28 | | -from dojo.finding.vulnerability_id import resolve_vulnerability_id_type |
29 | 28 |
|
30 | 29 | # get_current_date/tomorrow/copy_model_util are defined early in dojo.models, before the |
31 | 30 | # re-export that loads this module — so this resolves despite the partial circular load, and |
@@ -846,18 +845,11 @@ def _get_unsaved_vulnerability_ids(finding) -> str: |
846 | 845 |
|
847 | 846 | def _get_saved_vulnerability_ids(finding) -> str: |
848 | 847 | if finding.id is not None: |
849 | | - from dojo.vulnerability.queries import use_entity_reads # noqa: PLC0415 |
850 | | - if use_entity_reads(): |
851 | | - # Entity store: the prefetch-honoring reverse relation (vulnerability_references |
852 | | - # + select_related("vulnerability")) so Prefetch is honored — no N+1 in dedupe. |
853 | | - vulnerability_id_str_list = [ref.vulnerability.vulnerability_id for ref in finding.vulnerability_references.all()] |
854 | | - else: |
855 | | - # Use the reverse relation (vulnerability_id_set) rather than a fresh |
856 | | - # Vulnerability_Id.objects.filter(...) so prefetch_related("vulnerability_id_set") |
857 | | - # is honored — avoids an N+1 (COUNT + SELECT per finding) during dedupe/hashcode. |
858 | | - vulnerability_id_str_list = [str(vulnerability_id) for vulnerability_id in finding.vulnerability_id_set.all()] |
| 848 | + # Entity store: the prefetch-honoring reverse relation (vulnerability_references |
| 849 | + # + select_related("vulnerability")) so Prefetch is honored — no N+1 in dedupe. |
| 850 | + vulnerability_id_str_list = [ref.vulnerability.vulnerability_id for ref in finding.vulnerability_references.all()] |
859 | 851 | deduplicationLogger.debug("get_vulnerability_ids after the finding was saved. Vulnerability references count: " + str(len(vulnerability_id_str_list))) |
860 | | - # sort vulnerability_ids strings (no dedupe — byte parity with the legacy store) |
| 852 | + # sort vulnerability_ids strings (no dedupe — ordering is irrelevant to the hash) |
861 | 853 | return "".join(sorted(vulnerability_id_str_list)) |
862 | 854 | return "" |
863 | 855 |
|
@@ -1397,14 +1389,9 @@ def get_references_with_links(self): |
1397 | 1389 |
|
1398 | 1390 | @cached_property |
1399 | 1391 | def vulnerability_ids(self): |
1400 | | - from dojo.vulnerability.queries import use_entity_reads # noqa: PLC0415 |
1401 | | - # Get vulnerability ids from database and convert to list of strings |
1402 | | - if use_entity_reads(): |
1403 | | - # Entity store: reverse relation is ordered by FindingVulnerabilityReference.Meta.ordering. |
1404 | | - vulnerability_ids = [ref.vulnerability.vulnerability_id for ref in self.vulnerability_references.all()] |
1405 | | - else: |
1406 | | - vulnerability_ids_model = self.vulnerability_id_set.all() |
1407 | | - vulnerability_ids = [vulnerability_id.vulnerability_id for vulnerability_id in vulnerability_ids_model] |
| 1392 | + # Get vulnerability ids from database and convert to list of strings. |
| 1393 | + # Entity store: reverse relation is ordered by FindingVulnerabilityReference.Meta.ordering. |
| 1394 | + vulnerability_ids = [ref.vulnerability.vulnerability_id for ref in self.vulnerability_references.all()] |
1408 | 1395 |
|
1409 | 1396 | # Synchronize the cve field with the unsaved_vulnerability_ids |
1410 | 1397 | # We do this to be as flexible as possible to handle the fields until |
@@ -1452,39 +1439,9 @@ def set_hash_code(self, dedupe_option): |
1452 | 1439 | deduplicationLogger.debug("Hash_code computed for finding: %s: %s", finding_id, self.hash_code) |
1453 | 1440 |
|
1454 | 1441 |
|
1455 | | -class Vulnerability_Id(models.Model): |
1456 | | - finding = models.ForeignKey("dojo.Finding", editable=False, on_delete=models.CASCADE) |
1457 | | - vulnerability_id = models.TextField(max_length=50, blank=False, null=False) |
1458 | | - # Autodetected from the id prefix (CVE, GHSA, ...); NULL when there is no non-numeric |
1459 | | - # prefix. Denormalized/indexed so type-scoped queries (e.g. GROUP BY type) stay cheap. |
1460 | | - vulnerability_id_type = models.CharField(max_length=20, null=True, blank=True, editable=False, db_index=True) |
1461 | | - |
1462 | | - class Meta: |
1463 | | - constraints = [ |
1464 | | - models.UniqueConstraint(fields=["finding", "vulnerability_id"], name="unique_finding_vulnerability_id"), |
1465 | | - ] |
1466 | | - indexes = [ |
1467 | | - # Leading on vulnerability_id (the unique constraint's index leads on finding), for the |
1468 | | - # vulnerability-id Explorer's GROUP BY vulnerability_id / lookups by exact id. |
1469 | | - models.Index(fields=["vulnerability_id"], name="dojo_vuln_id_lookup_idx"), |
1470 | | - # Global search (pro/search/): weighted tsvector FTS + trigram fuzzy match. |
1471 | | - GinIndex( |
1472 | | - SearchVector("vulnerability_id", weight="A", config="english"), |
1473 | | - name="dojo_vulnerability_id_fts_gin", |
1474 | | - ), |
1475 | | - GinIndex(fields=["vulnerability_id"], opclasses=["gin_trgm_ops"], name="dojo_vuln_id_trgm"), |
1476 | | - ] |
1477 | | - |
1478 | | - def __str__(self): |
1479 | | - return self.vulnerability_id |
1480 | | - |
1481 | | - def save(self, *args, **kwargs): |
1482 | | - # bulk_create paths set the type at construction; this covers save()/get_or_create. |
1483 | | - self.vulnerability_id_type = resolve_vulnerability_id_type(self.vulnerability_id) |
1484 | | - super().save(*args, **kwargs) |
1485 | | - |
1486 | | - def get_absolute_url(self): |
1487 | | - return reverse("view_finding", args=[str(self.finding.id)]) |
| 1442 | +# The legacy Vulnerability_Id model was removed in the entity-only cutover; vulnerability ids now |
| 1443 | +# live in the Vulnerability entity + FindingVulnerabilityReference through-table (dojo/vulnerability/). |
| 1444 | +# The dojo_vulnerability_id table is dropped by migration 0287. |
1488 | 1445 |
|
1489 | 1446 |
|
1490 | 1447 | class Finding_CWE(models.Model): |
|
0 commit comments