summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--checklists/migrations/0007_alter_securityissue_cve_year_number.py29
-rw-r--r--checklists/models.py8
-rw-r--r--checklists/tests/test_models.py38
3 files changed, 73 insertions, 2 deletions
diff --git a/checklists/migrations/0007_alter_securityissue_cve_year_number.py b/checklists/migrations/0007_alter_securityissue_cve_year_number.py
new file mode 100644
index 00000000..0bc2811c
--- /dev/null
+++ b/checklists/migrations/0007_alter_securityissue_cve_year_number.py
@@ -0,0 +1,29 @@
+# Generated by Django 6.0.4 on 2026-05-07 02:32
+
+import django.core.validators
+from django.db import migrations, models
+
+import checklists.models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("checklists", "0006_remove_securityissue_attack_complexity_and_more"),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name="securityissue",
+ name="cve_year_number",
+ field=models.CharField(
+ default=checklists.models.get_cve_default,
+ max_length=1024,
+ unique=True,
+ validators=[
+ django.core.validators.RegexValidator(regex="CVE-\\d{4}-\\d{4,5}")
+ ],
+ verbose_name="CVE ID",
+ ),
+ ),
+ ]
diff --git a/checklists/models.py b/checklists/models.py
index ad44dbf7..41b9a2b1 100644
--- a/checklists/models.py
+++ b/checklists/models.py
@@ -2,7 +2,7 @@ import datetime
import json
from django.contrib.auth.models import User
-from django.core.validators import MaxValueValidator, MinValueValidator
+from django.core.validators import MaxValueValidator, MinValueValidator, RegexValidator
from django.db import models
from django.db.models.functions import Cast, Substr
from django.shortcuts import reverse
@@ -467,7 +467,11 @@ class SecurityIssue(models.Model):
choices=[(i, i) for i in ("DSF", "MITRE")],
)
cve_year_number = models.CharField(
- "CVE ID", max_length=1024, unique=True, default=get_cve_default
+ "CVE ID",
+ max_length=1024,
+ unique=True,
+ default=get_cve_default,
+ validators=[RegexValidator(regex=r"CVE-\d{4}-\d{4,5}")],
)
objects = SecurityIssueManager()
diff --git a/checklists/tests/test_models.py b/checklists/tests/test_models.py
index 73ad4851..192df301 100644
--- a/checklists/tests/test_models.py
+++ b/checklists/tests/test_models.py
@@ -3,6 +3,7 @@ import re
import zoneinfo
from datetime import UTC, date, datetime
+from django.core.exceptions import ValidationError
from django.db import IntegrityError
from django.template.loader import render_to_string
from django.test import RequestFactory, TestCase, override_settings
@@ -872,6 +873,43 @@ class GetCvssSeverityTests(TestCase):
self.assertEqual(get_cvss_severity(10.0), "CRITICAL")
+class SecurityIssueTestCase(TestCase):
+ def test_cve_year_number_invalid(self):
+ invalid_cve_numbers = [
+ "CVE-2026-1",
+ "CVE-2026-XXXX",
+ "CVE-20026-1111",
+ ]
+ for cve in invalid_cve_numbers:
+ with self.subTest(cve=cve):
+ with self.assertRaises(ValidationError) as context:
+ SecurityIssue(cve_year_number=cve).full_clean()
+
+ self.assertEqual(
+ context.exception.message_dict.get("cve_year_number"),
+ ["Enter a valid value."],
+ )
+
+ def test_cve_year_number_valid(self):
+ valid_cve_numbers = [
+ "CVE-2026-12345",
+ "CVE-2026-1234",
+ ]
+ for cve in valid_cve_numbers:
+ with self.subTest(cve=cve):
+ # No ValidationError raised.
+ SecurityIssue(cve_year_number=cve).full_clean(
+ exclude=(
+ "summary",
+ "description",
+ "cve_type",
+ "impact",
+ "confirmed_at",
+ "reported_at",
+ )
+ )
+
+
class CvssMetricsInCveDataTests(TestCase):
factory = Factory()