|
52 | 52 | from vulnerabilities.tests import make_vulnerability |
53 | 53 | from vulnerabilities.tests import make_vulnerability_analysis |
54 | 54 | from vulnerabilities.triage.engine import evaluate_ruleset |
| 55 | +from vulnerabilities.triage.models import ProductTriageRuleset |
55 | 56 | from vulnerabilities.triage.models import TriageAction |
56 | 57 | from vulnerabilities.triage.tests import make_product_triage_ruleset |
57 | 58 | from vulnerabilities.triage.tests import make_triage_ruleset |
@@ -801,6 +802,107 @@ def test_api_product_endpoint_triage_records_action(self): |
801 | 802 | self.assertIn("detected_date", entry) |
802 | 803 | self.assertIn("last_checked", entry) |
803 | 804 |
|
| 805 | + def test_api_product_endpoint_manage_triage_rulesets_get(self): |
| 806 | + url = reverse("api_v2:product-manage-triage-rulesets", args=[self.product1.uuid]) |
| 807 | + self.client.login(username=self.base_user.username, password="secret") |
| 808 | + response = self.client.get(url) |
| 809 | + self.assertEqual(status.HTTP_404_NOT_FOUND, response.status_code) |
| 810 | + |
| 811 | + add_perm(self.base_user, "add_product") |
| 812 | + assign_perm("view_product", self.base_user, self.product1) |
| 813 | + |
| 814 | + assigned_ruleset = make_triage_ruleset(self.dataspace, name="Assigned Ruleset") |
| 815 | + make_product_triage_ruleset(self.product1, ruleset=assigned_ruleset) |
| 816 | + unassigned_ruleset = make_triage_ruleset(self.dataspace, name="Unassigned Ruleset") |
| 817 | + make_triage_ruleset(self.dataspace, name="Disabled Ruleset", enabled=False) |
| 818 | + |
| 819 | + response = self.client.get(url) |
| 820 | + self.assertEqual(status.HTTP_200_OK, response.status_code) |
| 821 | + self.assertEqual(2, len(response.data)) |
| 822 | + entries_by_name = {entry["name"]: entry for entry in response.data} |
| 823 | + self.assertTrue(entries_by_name[assigned_ruleset.name]["assigned"]) |
| 824 | + self.assertFalse(entries_by_name[unassigned_ruleset.name]["assigned"]) |
| 825 | + self.assertNotIn("Disabled Ruleset", entries_by_name) |
| 826 | + |
| 827 | + def test_api_product_endpoint_manage_triage_rulesets_post_assigns(self): |
| 828 | + url = reverse("api_v2:product-manage-triage-rulesets", args=[self.product1.uuid]) |
| 829 | + self.client.login(username=self.base_user.username, password="secret") |
| 830 | + add_perm(self.base_user, "add_product") |
| 831 | + assign_perm("view_product", self.base_user, self.product1) |
| 832 | + assign_perm("change_product", self.base_user, self.product1) |
| 833 | + |
| 834 | + package = make_package(self.dataspace) |
| 835 | + make_product_package(self.product1, package=package) |
| 836 | + vulnerability = make_vulnerability(self.dataspace, affecting=package, risk_score=9.0) |
| 837 | + ruleset = make_triage_ruleset( |
| 838 | + self.dataspace, |
| 839 | + recommended_action=TriageAction.UPGRADE, |
| 840 | + rules_config={"risk_score": {"is_active": True, "min_risk_score": 8.0}}, |
| 841 | + ) |
| 842 | + |
| 843 | + data = {"ruleset": str(ruleset.uuid), "assigned": True} |
| 844 | + response = self.client.post(url, data=data, content_type="application/json") |
| 845 | + |
| 846 | + self.assertEqual(status.HTTP_200_OK, response.status_code) |
| 847 | + self.assertTrue( |
| 848 | + ProductTriageRuleset.objects.filter(product=self.product1, ruleset=ruleset).exists() |
| 849 | + ) |
| 850 | + triage_record = self.product1.triage_records.get() |
| 851 | + self.assertEqual(vulnerability, triage_record.vulnerability) |
| 852 | + |
| 853 | + def test_api_product_endpoint_manage_triage_rulesets_post_unassigns(self): |
| 854 | + url = reverse("api_v2:product-manage-triage-rulesets", args=[self.product1.uuid]) |
| 855 | + self.client.login(username=self.base_user.username, password="secret") |
| 856 | + add_perm(self.base_user, "add_product") |
| 857 | + assign_perm("view_product", self.base_user, self.product1) |
| 858 | + assign_perm("change_product", self.base_user, self.product1) |
| 859 | + |
| 860 | + ruleset = make_triage_ruleset(self.dataspace) |
| 861 | + make_product_triage_ruleset(self.product1, ruleset=ruleset) |
| 862 | + |
| 863 | + data = {"ruleset": str(ruleset.uuid), "assigned": False} |
| 864 | + response = self.client.post(url, data=data, content_type="application/json") |
| 865 | + |
| 866 | + self.assertEqual(status.HTTP_200_OK, response.status_code) |
| 867 | + self.assertFalse( |
| 868 | + ProductTriageRuleset.objects.filter(product=self.product1, ruleset=ruleset).exists() |
| 869 | + ) |
| 870 | + |
| 871 | + def test_api_product_endpoint_manage_triage_rulesets_post_requires_both_fields(self): |
| 872 | + url = reverse("api_v2:product-manage-triage-rulesets", args=[self.product1.uuid]) |
| 873 | + self.client.login(username=self.base_user.username, password="secret") |
| 874 | + add_perm(self.base_user, "add_product") |
| 875 | + assign_perm("view_product", self.base_user, self.product1) |
| 876 | + assign_perm("change_product", self.base_user, self.product1) |
| 877 | + |
| 878 | + response = self.client.post(url, data={}, content_type="application/json") |
| 879 | + |
| 880 | + self.assertEqual(status.HTTP_400_BAD_REQUEST, response.status_code) |
| 881 | + |
| 882 | + def test_api_product_endpoint_manage_triage_rulesets_post_rejects_non_dict_body(self): |
| 883 | + url = reverse("api_v2:product-manage-triage-rulesets", args=[self.product1.uuid]) |
| 884 | + self.client.login(username=self.base_user.username, password="secret") |
| 885 | + add_perm(self.base_user, "add_product") |
| 886 | + assign_perm("view_product", self.base_user, self.product1) |
| 887 | + assign_perm("change_product", self.base_user, self.product1) |
| 888 | + |
| 889 | + response = self.client.post(url, data=[], content_type="application/json") |
| 890 | + |
| 891 | + self.assertEqual(status.HTTP_400_BAD_REQUEST, response.status_code) |
| 892 | + |
| 893 | + def test_api_product_endpoint_manage_triage_rulesets_post_rejects_disabled_ruleset(self): |
| 894 | + url = reverse("api_v2:product-manage-triage-rulesets", args=[self.product1.uuid]) |
| 895 | + self.client.login(username=self.base_user.username, password="secret") |
| 896 | + add_perm(self.base_user, "add_product") |
| 897 | + assign_perm("view_product", self.base_user, self.product1) |
| 898 | + assign_perm("change_product", self.base_user, self.product1) |
| 899 | + |
| 900 | + ruleset = make_triage_ruleset(self.dataspace, enabled=False) |
| 901 | + data = {"ruleset": str(ruleset.uuid), "assigned": True} |
| 902 | + response = self.client.post(url, data=data, content_type="application/json") |
| 903 | + |
| 904 | + self.assertEqual(status.HTTP_404_NOT_FOUND, response.status_code) |
| 905 | + |
804 | 906 |
|
805 | 907 | class ProductRelatedAPITestCase(TestCase): |
806 | 908 | def setUp(self): |
|
0 commit comments